home *** CD-ROM | disk | FTP | other *** search
- ; Co.asm
- ;COPYRIGHT DB 10,"CO 1.0 (c) 1987 Ziff Communications Co.",13, 10
- ;PROGRAMMER DB 26,"Michael J. Mefford" SET_ENV_LGTH DB 0
- ; Format CO [d:][directory]
- ;
- ;Michael J. Mefford 1987/No. 21 (Utilities)
- ;
- ;This is a modified version of PC Magazines CO Utility
- ;It has Been modified for some special batch tasks.
- ;Several new parameters have been added.
- ;
- ;Purpose:
- ;Select, Copy, move, or delete file(s) individually or in tagged
- ;groups from directory listings sorted by name, extension, size, or date.
- ;
- ;One special function will place the file name selected in the
- ;environment variable FILE=name. You may view it with the set command.
- ;
- ;Format:
- ;CO [d:][\directory 1] [d:][\directory 2] [/E][/S][/D][/T][/O]
- ; [/M3] [/M4]
- ;
- ;Directory 1 - CO will read and display files in this directory
- ;Directory 2 - CO will only copy to this direcory when this parameter
- ; is entered.
- ;
- ;/E - Sort Files by file extension.
- ;/S - Sort Files by file size.
- ;/D - Sort Files by Date and time.
- ;/T - Sort Files by Date and time.
- ;/O - Don't Sort Files leave in order DOS put them.
- ;/M3 - Special setup for copying models to start a program
- ;/M4 - Start with Long menu (RN call with this parm).
- ;
- ;Program Functions:
- ;
- ; ╔═════════════════════════════╗
- ; ║ PC Magazine CO.COM ║
- ; ╟─────────────────────────────╢
- ; ║ Enter ─┘ Select & End Pgm ║
- ; ║ ║
- ; ║ F3 ^Sort directory names ║
- ; ║ F4 ^Browse selected file ║
- ; ║ F5 ^Rename File(s) ║
- ; ║ F6 ^Delete File(s) ║
- ; ║ F7 ^Copy File(s) ║
- ; ║ F8 ^Move File(s) ║
- ; ║ F9 Mark all files ║
- ; ║ F10 Clear all marked Files ║
- ; ║ Toggles (on/off) ║
- ; ║ √^Verify ^EBCDIC ^Wordstar║
- ; ║ +/- Ins/Del to Mark/Unmark ║
- ; ║ Esc to Cancel Program ║
- ; ╚═════════════════════════════╝
- ; Use: PgUp PgDn
- ; ^PgUp ^PgDn Home End
- ;
- ;
- ;Modified by Bob Hunt 414-287-3308
-
- CODE SEGMENT ;********************************;
- ASSUME CS:CODE,DS:CODE ;* *;
- ORG 100H ;* Requires MASM 2.0 or later *;
- ;* Remember to EXE2BIN *;
- START: JMP BEGINNING ;* *;
- ;********************************;
-
- ;
- ; DATA AREA
-
- ; PC HOST
- ; ---------- --------
- EBCDIC_TR DB 000H ;nul 00 . nul
- DB 001H ;soh . 01 . soh
- DB 002H ;stx . 02 . stx
- DB 003H ;etx . 03 . etx
- DB 004H ;eot . 04 . sel
- DB 009H ;ht . 05 . ht
- DB 006H ;ack . 06 . rnl
- DB 07FH ;del . 07 . del
- DB 008H ;bs 08 . ge
- DB 009H ;ht 09 . sps
- DB 00AH ;lf 0A . rpt
- DB 00BH ;vt 0B . vt
- DB 00CH ;ff 0C . ff
- DB 00DH ;cr 0D . cr
- DB 00EH ;so 0E . so
- DB 00FH ;si 0F . si
- DB 010H ;dle 10 . dle
- DB 011H ;dc1 11 . dc1
- DB 012H ;dc2 12 . dc2
- DB 013H ;dc3 13 . dc3
- DB 014H ;dc4 14 . res/enp
- DB 015H ;nak . 15 . nl
- DB 008H ;bs 16 . bs
- DB 017H ;etb . 17 . poc
- DB 018H ;can . 18 . can
- DB 019H ;em . 19 . em
- DB 01AH ;sub 1A . ubs
- DB 01BH ;esc 1B . cu1
- DB 01CH ;fs 1C . ifs
- DB 01DH ;gs . 1D . igs
- DB 01EH ;rs . 1E . irs
- DB 01FH ;us . 1F . itb/ius
- DB 020H ;sp 20 . ds
- DB 021H ; ! 21 . sos
- DB 01CH ;fs 22 . fs
- DB 023H ; # 23 . wus
- DB 024H ; $ 24 . byp/inp
- DB 00AH ;lf 25 . lf
- DB 017H ;etb . 26 . etb
- DB 01BH ;esc 27 . esc
- DB 028H ; ( 28 . sa
- DB 029H ; ) 29 . sfe
- DB 02AH ; * 2A . sm/sw
- DB 02BH ; + 2B . csp
- DB 02CH ; , 2C . mfa
- DB 005H ; - 2D . enq
- DB 006H ;ack . 2E . ack
- DB 007H ;bel 2F . bel
- ;
- ; PC HOST
- ; ---------- --------
- DB 030H ; 0 30 .
- DB 031H ; 1 31 .
- DB 016H ;syn . 32 . syn
- DB 033H ; 3 33 . ir
- DB 034H ; 4 34 . pp
- DB 01EH ;rs . 35 . trn
- DB 036H ; 6 36 . nbs
- DB 004H ;eot . 37 . eot
- DB 038H ; 8 38 . sbs
- DB 039H ; 9 39 . it
- DB 03AH ; : 3A . rff
- DB 03BH ; ; 3B . cu3
- DB 014H ;dc4 3C . dc4
- DB 015H ;nak . 3D . nak
- DB 03EH ; > 3E .
- DB 01AH ;sub 3F . sub
- DB 020H ;sp 40 sp
- DB 041H ; A 41
- DB 042H ; B 42
- DB 043H ; C 43
- DB 044H ; D 44
- DB 045H ; E 45
- DB 046H ; F 46
- DB 047H ; G 47
- DB 048H ; H 48
- DB 049H ; I 49
- DB 09BH ; 4A
- DB 02EH ; . 4B .
- DB 03CH ; < 4C <
- DB 028H ; ( 4D (
- DB 02BH ; + 4E +
- DB 0B3H ; . 4F .
- DB 026H ; & 50 &
- DB 051H ; Q 51
- DB 052H ; R 52
- DB 053H ; S 53
- DB 054H ; T 54
- DB 055H ; U 55
- DB 056H ; V 56
- DB 057H ; W 57
- DB 058H ; X 58
- DB 059H ; Y 59
- DB 021H ; ! 5A !
- DB 024H ; $ 5B $
- DB 02AH ; * 5C *
- DB 029H ; ) 5D )
- DB 03BH ; ; 5E ;
- DB 05EH ; ^ 5F ^
- ;
- ;
- ; PC HOST
-
- ; -------- --------
- DB 02DH ; - 60 -
- DB 02FH ; / 61 /
- DB 062H ; b 62
- DB 063H ; c 63
- DB 064H ; d 64
- DB 065H ; e 65
- DB 066H ; f 66
- DB 067H ; g 67
- DB 068H ; h 68
- DB 069H ; i 69
- DB 07CH ; | 6A |
- DB 02CH ; , 6B ,
- DB 025H ; % 6C %
- DB 05FH ; _ 6D _
- DB 03EH ; > 6E >
- DB 03FH ; ? 6F ?
- DB 070H ; p 70
- DB 071H ; q 71
- DB 072H ; r 72
- DB 073H ; s 73
- DB 074H ; t 74
- DB 075H ; u 75
- DB 076H ; v 76
- DB 077H ; w 77
- DB 078H ; x 78
- DB 060H ; ` 79 `
- DB 03AH ; : 7A :
- DB 023H ; # 7B #
- DB 040H ; @ 7C @
- DB 027H ; ' 7D '
- DB 03DH ; = 7E =
- DB 022H ; " 7F "
- DB 080H ; 80 .
- DB 061H ; a 81 a
- DB 062H ; b 82 b
- DB 063H ; c 83 c
- DB 064H ; d 84 d
- DB 065H ; e 85 e
- DB 066H ; f 86 f
- DB 067H ; g 87 g
- DB 068H ; h 88 h
- DB 069H ; i 89 i
- DB 08AH ; 8A .
- DB 08BH ; 8B {
- DB 08CH ; 8C .
- DB 08DH ; 8D .
- DB 08EH ; 8E .
- DB 08FH ; 8F .
- ;
- ; PC HOST
- ; ---------- --------
- DB 090H ; 90 .
- DB 06AH ; j 91 j
- DB 06BH ; k 92 k
- DB 06CH ; l 93 l
- DB 06DH ; m 94 m
- DB 06EH ; n 95 n
- DB 06FH ; o 96 o
- DB 070H ; p 97 p
- DB 071H ; q 98 q
- DB 072H ; r 99 r
- DB 09AH ; 9A .
- DB 09BH ; 9B }
- DB 09CH ; . 9C .
- DB 09DH ; . 9D .
- DB 09EH ; . 9E .
- DB 09FH ; . 9F .
- DB 0A0H ; . A0 .
- DB 07EH ; ~ A1 ~
- DB 073H ; s A2 s
- DB 074H ; t A3 t
- DB 075H ; u A4 u
- DB 076H ; v A5 v
- DB 077H ; w A6 w
- DB 078H ; x A7 x
- DB 079H ; y A8 y
- DB 07AH ; z A9 z
- DB 0AAH ; . AA .
- DB 0ABH ; . AB .
- DB 0ACH ; . AC .
- DB 05BH ; [ AD [
- DB 0AEH ; . AE .
- DB 0AFH ; . AF .
- DB 0B0H ; . B0 .
- DB 0B1H ; . B1 .
- DB 0B2H ; . B2 .
- DB 0B3H ; . B3 .
- DB 0B4H ; . B4 .
- DB 0B5H ; . B5 .
- DB 0B6H ; . B6 .
- DB 0B7H ; . B7 .
- DB 0B8H ; . B8 .
- DB 0B9H ; . B9 .
- DB 0BAH ; . BA .
- DB 0BBH ; . BB .
- DB 0BCH ; . BC .
- DB 05DH ; ] BD ]
- DB 0BEH ; . BE .
- DB 0BFH ; . BF .
- ;
- ; PC HOST
- ; ---------- --------
- DB 07BH ; { C0 {
- ; DB 0C0H ; . C0 {
- DB 041H ; A C1 A
- DB 042H ; B C2 B
- DB 043H ; C C3 C
- DB 044H ; D C4 D
- DB 045H ; E C5 E
- DB 046H ; F C6 F
- DB 047H ; G C7 G
- DB 048H ; H C8 H
- DB 049H ; I C9 I
- DB 0CAH ; . CA .
- DB 0CBH ; . CB .
- DB 0CCH ; . CC .
- DB 0CDH ; . CD .
- DB 0CEH ; . CE .
- DB 0CFH ; . CF .
- DB 07DH ; } D0 }
- DB 04AH ; J D1 J
- DB 04BH ; K D2 K
- DB 04CH ; L D3 L
- DB 04DH ; M D4 M
- DB 04EH ; N D5 N
- DB 04FH ; O D6 O
- DB 050H ; P D7 P
- DB 051H ; Q D8 Q
- DB 052H ; R D9 R
- DB 0DAH ; . DA .
- DB 0DBH ; . DB .
- DB 0DCH ; . DC .
- DB 0DDH ; .DD .
- DB 0DEH ; .DE .
- DB 0DFH ; .DF .
- DB 05CH ; \ E0 \
- DB 0E1H ; . E1 .
- DB 053H ; S E2 S
- DB 054H ; T E3 T
- DB 055H ; U E4 U
- DB 056H ; V E5 V
- DB 057H ; W E6 W
- DB 058H ; X E7 X
- DB 059H ; Y E8 Y
- DB 05AH ; Z E9 Z
- DB 0EAH ; . EA .
- DB 0EBH ; . EB .
- DB 0ECH ; . EC .
- DB 0EDH ; . ED .
- DB 0EEH ; . EE .
- DB 0EFH ; . EF .
- ;
- ; PC HOST
- ; ---------- --------
- DB 030H ; 0 F0 0
- DB 031H ; 1 F1 1
- DB 032H ; 2 F2 2
- DB 033H ; 3 F3 3
- DB 034H ; 4 F4 4
- DB 035H ; 5 F5 5
- DB 036H ; 6 F6 6
- DB 037H ; 7 F7 7
- DB 038H ; 8 F8 8
- DB 039H ; 9 F9 9
- DB 0FAH ; . FA .
- DB 0FBH ; . FB .
- DB 0FCH ; . FC .
- DB 0FDH ; . FD .
- DB 0FEH ; . FE .
- DB 0FFH ; FF .
- ;
- SET_ENV_lgth DB 0
- DB "FILE="
- SET_ENV_NAME DB 13 DUP (00)
- RN_SWITCH DB 32 ;SET IF RN CALLS US
- TEMPUS_RETCODE DB 3
- MENU_TYPE DB 0 ; MENU TYPE FROM PARMS
- M4 DB 0 ; M4 ENTERED = 4
- TEMPUS DB '\dos\command /C COPYU '
- TEMPUS_FILE DB 85 DUP (00)
- INPUT_DIR DB 40 DUP (00)
- OUTPUT_DIR DB 40 DUP (00)
- VIEW_DIR DB 69 DUP (00)
- LGTH_DIR EQU 32
-
- SAVE_KEY DB 0
- FIELD_SIZE EQU 44
- PAGE_START EQU 323
- BAR_START EQU PAGE_START
- BAR_OFFSET EQU 3 ;BAR OFFSET FROM BEGGINING OF LINE
- BAR_LENGTH EQU 44
- COPY_MARK EQU 16
- COPY_MARK_DONE EQU 46
- FCB EQU 5CH
-
- CURRENT_DISK DB ?
- STATUS_REG DW ?
- VIDEO_SEG DW 0B000H
- NORMAL DB 07H
- INVERSE DB 70H
- BAR_ATTRIBUTE DB 70H
- ATTR_TREE DB 07H
- ATTR_MENU DB 07H
- ATTR_TEXT DB 07H
- ATTR_MSGS DB 07H
- ATTR_SAVE DB 07H
- CURSOR_TYPE DW ?
- CUR_VERIFY DB 0
-
- SORT_OFFSET DW 0
- SORT_TABLE DW 0,12,9,3,13,8,29
- SORT_FLAG DB 0
- SEARCH_ATTRIB DW 17H
- CUR_OFFSET DW BUFFER
- CUR_FILE DW ?
- END_OFFSET DW ?
- PAGE_END DW 21 * 160 + BAR_START
- COUNT DW 0
- FILE_CNT DW 0
- LINE DW BAR_START
- SEARCH_COUNT DW ?
-
- MARK_CNT DW 0
- FILENAME_END DW ?
- PURGE_DISK DB ?
- READ_HANDLE DW ?
- WRITE_HANDLE DW ?
- SOURCE_ATTRIB DW ?
- TARGET_ATTRIB DW ?
- SIZE_LOW DW ?
- SIZE_HIGH DW ?
- SOURCE_TIME DW ?
- SOURCE_DATE DW ?
- FILE_NAME DW 8 DUP(0)
- COPY_FLAG DB 0
- DELETE_FLAG DB 0
- RENAME_FLAG DB 0
- RENAME_FILE_FLAG DB 0
- VERIFY_FLAG DB 1
-
- ERROR_EXEC DB 0 ; ERROR FOR EXEC_MARKED
-
- K_ESC EQU 1
- K_MINUS EQU 12
- K_PLUS EQU 13
- K_BACKSPACE EQU 14
- K_TAB EQU 15
- K_Q EQU 16
- K_W EQU 17
- K_E EQU 18
- K_R EQU 19
- K_T EQU 20
- K_Y EQU 21
- K_U EQU 22
- K_I EQU 23
- K_O EQU 24
- K_P EQU 25
- K_L_BRACKET EQU 26
- K_R_BRACKET EQU 27
- K_ENTER EQU 28
- K_S EQU 31
- K_D EQU 32
- K_C EQU 46
- K_V EQU 47
- K_B EQU 48
- K_N EQU 49
- K_M EQU 50
- K_F1 EQU 59
- K_F2 EQU 60
- K_F3 EQU 61
- K_F4 EQU 62
- K_F5 EQU 63
- K_F6 EQU 64
- K_F7 EQU 65
- K_F8 EQU 66
- K_F9 EQU 67
- K_F10 EQU 68
- K_NUM_LOCK EQU 69
- K_SCROLL_LOCK EQU 70
- K_HOME EQU 71
- K_UP_ARROW EQU 72
- K_PGUP EQU 73
- K_PRTSC EQU 55
- KN_MINUS EQU 74
- K_LEFT_ARROW EQU 75
- K_RIGHT_ARROW EQU 77
- KN_PLUS EQU 78
- K_END EQU 79
- K_DOWN_ARROW EQU 80
- K_PGDN EQU 81
- K_INS EQU 82
- K_DEL EQU 83
- K_LEFT_SHIFT EQU 42
- K_RIGHT_SHIFT EQU 36
- K_TAB EQU 15
- K_CTRL EQU 29
- K_ALT EQU 56
- K_SPACE EQU 57
- K_CAPS_LOCK EQU 58
- K_CTRL_PGDN EQU 118
- K_CTRL_PGUP EQU 132
-
- DEFAULT_MENU DB 2 ;DEFAULT IS MENU 2
-
- DISPATCH_KEY DB K_ESC, K_F7, K_F6, K_F8
- DB K_ENTER
- DB K_F10, K_F9
- DB KN_MINUS, KN_PLUS
- DB K_MINUS, K_PLUS
- DB K_DEL, K_INS
- DB K_F4
- DB K_B
- DB K_F5
- DB K_R
- DISPATCH_KF2 DB K_F2
- DB K_F3
- DB K_S
- DB K_E
- DB K_W
- ; DB K_T, K_S, K_N
- DB K_D, K_C, K_V,
- DB K_M,
- DB K_HOME, K_UP_ARROW, K_PGUP
- DB K_END, K_DOWN_ARROW, K_PGDN, K_CTRL_PGDN
- DB K_CTRL_PGUP
- DB K_LEFT_ARROW
- DB K_RIGHT_ARROW
- DISPATCH_CNT EQU $ - DISPATCH_KEY
-
- DISPATCH_TABLE DW ESC_EXIT, COPY, DELETE, MOVE,
- DW SELECT
- DW CLEAR_MARK, MARK_BLANK
- DW UNMARK, MARK
- DW UNMARK, MARK
- DW UNMARK, MARK
- DW VIEW
- DW VIEW
- DW RENAME
- DW RENAME
- DISPATCH_F2 DW NO_OP
- DW SORT_TYPE
- DW SORT_TYPE
- DW EBCDIC
- DW WORDSTAR
- ; DW SORT_DATE, SORT_SIZE, SORT_NAME
- DW DELETE, COPY, VERIFY,
- DW MOVE,
- DW HOME_BAR, UP_ARROW, PG_UP
- DW END_BAR, DN_ARROW, PG_DN, BOTTOM_BAR,
- DW TOP_BAR
- DW MARK_UNMARK
- DW TO_MENU
- DISPATCH_END EQU $ - 2
-
- ;------------------FW MENU2---------------------------------------
- DISPATCH_KEY2 DB K_ESC
- DB K_ENTER
- DB K_F4
- DISPATCH_KF2_2 DB K_F2
- DB K_HOME, K_UP_ARROW, K_PGUP
- DB K_END, K_DOWN_ARROW, K_PGDN, K_CTRL_PGDN
- DB K_CTRL_PGUP
- DB K_RIGHT_ARROW
- DISPATCH_CNT2 EQU $ - DISPATCH_KEY2
-
- DISPATCH_TABLE2 DW ESC_EXIT
- DW SELECT
- DW NEW_MENU
- DISPATCH_F2_2 DW NO_OP
- DW HOME_BAR, UP_ARROW, PG_UP
- DW END_BAR, DN_ARROW, PG_DN, BOTTOM_BAR,
- DW TOP_BAR
- DW TO_MENU
- DISPATCH_END2 EQU $ - 2
- ;-----------------------------------------------------------------
-
- ;-----------------VIEW DATA-----------------------------------------
- BP_STACK EQU 20480
- FILE_BUFFER EQU 32767-500
- SIXTEEN_K EQU 16384
- PAGES DW ?
- DISPLAY_FLAG DB ?
- ROW DB 0
- FILE_END DW ?
- FILE_HANDLE DW ?
- LAST_PAGE DW ?
- WORDSTAR_BIT DB 7FH
- EBCDIC_FLAG DB 0
-
- VIEW_KEY DB K_ESC, K_ENTER,
- DB K_HOME, K_UP_ARROW, K_PGUP, K_END
- DB K_DOWN_ARROW, K_PGDN, K_CTRL_PGDN, K_CTRL_PGUP
- VIEW_CNT EQU $ - VIEW_KEY
-
- VIEW_TABLE DW VIEW_END, VIEW_END
- DW HOME_FILE, UP_LINE, UP_PG, END_FILE
- DW DN_LINE, DN_PG, END_FILE, HOME_FILE
- VIEW_TABLE_END EQU $ - 2
- ;-------------------------------------------------------------------
-
- MENU_WIDTH EQU 31
- MENU_LGTH EQU 20
-
- MENU LABEL BYTE
- DB 201,29 DUP (205), 187
- DB 186," PC Magazine CO.COM ",186
- DB 199,29 DUP (196) ,182
- DB 186," Enter ",17,196,217," Select & End Pgm ",186
- MENU_F2 DB 186," ",186
- DB 186," F3 ^Sort directory names ",186
- DB 186," F4 ^Browse selected file ",186
- DB 186," F5 ^Rename File(s) ",186
- DB 186," F6 ^Delete File(s) ",186
- DB 186," F7 ^Copy File(s) ",186
- DB 186," F8 ^Move File(s) ",186
- DB 186," F9 Mark all files ",186
- DB 186," F10 Clear all marked Files ",186
- DB 186," Toggles (on/off) ",186
- OPTION_LN DB 186," √^Verify ^EBCDIC ^Wordstar",186
- VERIFY_ON EQU OPTION_LN+2
- EBCDIC_ON EQU OPTION_LN+11
- WORDSTAR_ON EQU OPTION_LN+20
- DB 186," +/- Ins/Del to Mark/Unmark ",186
- DB 186," Esc to Cancel Program ",186
- DB 200,29 DUP (205), 188
- DB " Use: ",24,32,25," PgUp PgDn "
- DB " ^PgUp ^PgDn Home End "
-
- ;-----------------FW MENU2-------------------------------
- MENU2 LABEL BYTE
- DB 201,29 DUP (205),187,
- DB 186," PC Magazine CO.COM ",186
- DB 199,29 DUP (196),182
- DB 186,'To SELECT, use the ',24,' ',25,' cursor',186
- DB 186,' keys or the mouse to move ',186
- DB 186,' the HIGHLIGHTED box to the ',186
- DB 186,' File you wish, then press ',186
- DB 186,' the left mouse botton or the',186
- DB 186,'Enter ',17,196,217,' key. ',186
- DB 186,' ',186
- MENU_F2_2 DB 186," ",186
- DB 186,' ',186
- DB 186,' ',186
- DB 186,' F4 Maintenance functions ',186
- DB 186,' for files. ',186
- DB 186,' ',186
- DB 186,' Esc to Cancel Program ',186
- DB 200,29 DUP (205),188,
- DB ' Use: ',24,32,25,' PgUp PgDn '
- DB ' ^PgUp ^PgDn Home End '
-
- MENU_M3 DB 186," F2 New Project Copy File ",186,0
-
- NOT_ENOUGH DB "Requires 128K free RAM$"
- INVALID DB "Invalid directory$"
- TOO_MANY DB "Too many files$"
- LOADING DB "Loading and Sorting directory.",0
- LOAD_ONLY DB "Loading directory.",0
- NO_FILES DB "NO FILES FND",0
- DIRECTORY DB "Directory of ",0
- COPY_MOVE DB " [NOTE: Copy & Move functions SEND Data to -",16,32,0
- FILES DB 4 DUP(32),"File(s)",11 DUP(32),"bytes free",0
- DELETE_MSG DB " will be Deleted.",0,"Do you wish to delete? Y/N",0
- BS DB 8,32,8,0
- DISK_MSG DB "Error reading drive ",0
- DB "(R)etry or (Q)uit",0
- MARKED_MSG DB " marked files",0
- COPY_MSG DB "Copy ",0
- COPY_MODEL_MSG DB "Enter New Project name ",0
- COPY_MODEL_MSG2 DB "for copy of ",0
- MODEL DB "MODEL"
- BAK DB ".BAK"
- COPY_MODEL_ERR DB "Only one file can be selected!",0
- MOVE_MSG DB "Move ",0
- RENAME_MSG DB "Rename ",0
- TO_MSG DB " to...",0
- STAR_DOT_STAR DB "*.*",11 DUP (0)
- SAVE_LAST_SLASH DW ?
- IS_THERE_FILE DB 0
- ON DB " ON",0
- OFF DB "OFF",0
- DIRECTORIES DB "<DIR>"
- SORT_MSG1 DB "Enter type of sort for files",0
- SORT_MSG2 DB "Name Extention Size Date or Time",0
-
-
- ;----------------------------------------------------------------------------;
- ; Some housekeeping first. Since we will be changing the default drive
- ;
- ; and directory to the requested drive and directory, we need to save the
- ;
- ; current defaults, so they can be restored. Install critical error trap
- ;----------------------------------------------------------------------------;
-
- ; CODE AREA
- ; ---------
- BEGINNING: MOV AX,3301H ;Turn Control Break off.
- MOV DL,0
- INT 21H
-
- MOV AH,54H ;Get current verify flag.
- INT 21H
- MOV CUR_VERIFY,AL ; and save.
- MOV AL,01
- CALL SET_VERIFY ;Turn verify oN
- MOV DX,OFFSET DISK_ERROR ;Install critical error trap
- MOV AX,2524H
- INT 21H
-
- CLD ;String moves forward.
- CALL GET_DRIVE ;Get current drive.
- MOV CURRENT_DISK,AL ;Save.
- MOV SI,OFFSET CURRENT_DIR ;Get current directory.
- CALL GET_DIR
-
- ;---------------------------------------------------------------------;
- ; More housekeeping. We will be writing directly to the screen buffer ;
- ; so we need the display card address and the status register. ;
- ;---------------------------------------------------------------------;
-
- DISPLAY: MOV AX,40H ;Point to the ROM BIOS data area
- MOV DS,AX ; and get base address of active
- MOV AX,DS:[63H] ; display card.
- ADD AX,6 ;Add six to get status register
- PUSH CS ;Done there, so restore data segment.
- POP DS
- MOV STATUS_REG,AX ;Store status register.
- CMP AX,3BAH ;Status port of MONO card is 3BAh.
- JZ MONO ;If that's what we got, it's MONO
- MOV VIDEO_SEG,0B800H ; else COLOR so add 800h.
- XOR BH,BH ;Get current attribute
- MOV AH,8 ; of display page zero.
- INT 10H
- MOV NORMAL,AH ;Store it.
- MOV AH,07
- XOR AH,1110111xB ;Flip color bits.
- MOV INVERSE,AH ;Save it.
- MOV BAR_ATTRIBUTE,AH
- MOV ATTR_TREE,14 ;Store it.
- MOV ATTR_MENU,03 ;Store it.
- MOV ATTR_TEXT,02 ;Store it.
- MOV ATTR_MSGS,04 ;Store it.
- MONO: XOR BH,BH
- MOV AH,3 ;Retrieve cursor type.
- INT 10H
- MOV CURSOR_TYPE,CX
-
- MOV AH,49H ;Return our memory segment.
- INT 21H
-
- MOV BX,2000H ;Request 128K.
- MOV AH,4AH
- INT 21H
- MOV DX,OFFSET NOT_ENOUGH
- JNC PARSE
- JMP ERROR_EXIT ;If not available, exit.
-
- ;----------------------------------------;
- ; Parse the command line for parameters. ;
- ;----------------------------------------;
-
- PARSE: MOV SI,81H ;Point to first character.
- CMP BYTE PTR DS:[80H],0 ; Any parameters?
- JNZ NEXT_SWITCH
- JMP GET_WORKING ;If no, skip.
-
- NEXT_SWITCH: LODSB ;Get a byte.
- CMP AL,13 ;Carriage return?
- JNE NEXT_SWITCH_1
- JMP GET_PARA ;If yes, done here.
- NEXT_SWITCH_1: CMP AL,"-" ;Is it RN switch character?
- JNZ NEXT_REG_SW ;If no, CHECK next character
- MOV RN_SWITCH,"-" ;SET IT
-
- JMP NEXT_LOAD
- NEXT_REG_SW: CMP AL,"/" ;Is it switch character?
- JNZ NEXT_SWITCH ;If no, get next character.
- NEXT_LOAD: LODSB ;Get switch character.
- AND AL,5FH ;Capitalize.
- CMP AL,"R" ;If "R", remove directories.
- JNZ CK_EXT
- MOV SEARCH_ATTRIB,7
- CK_EXT: CMP AL,"E" ;If "E", sort by extension.
- JNZ CK_SIZE
- MOV SORT_OFFSET,4
- CK_SIZE: CMP AL,"S" ;If "S", sort by size.
- JNZ CK_DATE
- MOV SORT_OFFSET,8
- CK_DATE: CMP AL,"D" ;If "D", sort by date.
- JZ GOT_DATE
- CMP AL,"T" ;If "T", sort by date.
- JNZ CK_ORIGINAL
- GOT_DATE: MOV SORT_OFFSET,12
-
- CK_ORIGINAL: CMP AL,"O" ;If "O", don't sort at all.
- JNZ CK_MENU
- MOV SORT_FLAG,1
- CK_MENU: CMP AL,"M" ;If "M", M1,M2,M3.....
- JNE NEXT_SWITCH
- LODSB ;Get switch character.
- MOV MENU_TYPE,AL ;SAVE TYPE
- CMP AL,"3" ;/m3
- JNE CK_MENU_4
- MOV SI,OFFSET MENU_M3 ;NEW MENU LINE
- MOV DI,OFFSET MENU_F2 ;WHERE TO MOVE
- CALL MOVE_TEXT ;MOVE IT
- MOV SI,OFFSET MENU_M3 ;NEW MENU LINE
- MOV DI,OFFSET MENU_F2_2 ;WHERE TO MOVE
- CALL MOVE_TEXT ;MOVE IT
- MOV BX,OFFSET COPY_MODEL
- MOV WORD PTR DISPATCH_F2,BX ;NEW
- MOV WORD PTR DISPATCH_F2_2,BX ;NEW
-
- CK_MENU_4: CMP AL,"4" ;/m4
- JNE CK_NEXT_MENU
- MOV DEFAULT_MENU,1 ;DEFAULT TO LONG MENU
- MOV M4,4 ;SAY M4 ENTERED
-
- CK_NEXT_MENU:
- JMP SHORT NEXT_SWITCH
-
- GET_PARA: XOR BL,BL ;Assume no drive request.
- MOV SI,81H ;Point to first character.
-
- NEXT_PARA: MOV DI,OFFSET INPUT_DIR
- CMP INPUT_DIR,00 ;IF INPUT BLANK
- JZ NEXT_SCAN ;GOOD
- MOV DI,OFFSET OUTPUT_DIR ;ELSE POINT TO OUTPUT DIR
- NEXT_SCAN: LODSB
- NEXT_SCAN_1: CMP AL,32 ;End of parameter?
- JE NEXT_SCAN ;If yes, NEXT BYTE.
- CMP AL,13 ;End of parameter?
- JE END_PARA ;If yes, done here.
-
- CMP AL,"-"
- JE NEXT_BLANK_P
- CMP AL,"/"
- JE NEXT_BLANK_P
- MOV CX,LGTH_DIR
- DEC CX
- STOSB
- NEXT_LOOP: LODSB
- CMP AL,13 ;End of parameter?
- JE END_PARA ;If yes, done here.
- CMP AL,32 ;End of parameter?
- JE NEXT_PARA ;If yes, NEXT PARAMETER
-
- CMP AL,64
- JBE NO_CAPS
- AND AL,5FH ;Capitalize.
- NO_CAPS: STOSB
- DEC CX
- JZ NEXT_PARA
- JMP NEXT_LOOP ; GET NEXT CHAR
-
- NEXT_BLANK_P: LODSB
- CMP AL,13 ;End of parameter?
- JE END_PARA ;If yes, done here.
- CMP AL,32 ;End of parameter?
- JNE NEXT_BLANK_P ;If NO, NEXT BYTE.
- JMP NEXT_SCAN_1 ; GET PARAMETER
-
- END_PARA: CMP RN_SWITCH,32 ;DID RN CALL
- JNE NO_DRIVE_CHG
- CMP INPUT_DIR+1,":" ;DRIVE REQUEST
- JNE NO_DRIVE_CHG
- MOV DL,INPUT_DIR
- SUB DL,"A" ;Convert to DOS format.
- CALL CHANGE_DRIVE ;And change drive.
- NO_DRIVE_CHG: MOV SI,OFFSET INPUT_DIR
- MOV SAVE_LAST_SLASH,SI ;SAVE POINTER
- PARA_LOOP: MOV AL,BYTE PTR [SI] ;LOAD CHAR
- CMP AL,00 ;FIND END OF PARAMETER
- JE PARA_LOOP_END
- CHECK_COLEN: CMP AL,':' ;IS THERE A :
- JNE CHECK_SLASH
- MOV SAVE_LAST_SLASH,SI ;SAVE POINTER
- CHECK_SLASH: CMP AL,'\' ;IS THERE A \
- JNE CHECK_ASTRISK
- MOV SAVE_LAST_SLASH,SI ;SAVE POINTER
- CHECK_ASTRISK: CMP AL,'*' ;IS THERE A *
- JNE CHECK_QUESTION
- MOV IS_THERE_FILE,1 ;SAY YES
- CHECK_QUESTION: CMP AL,'?' ;IS THERE A ?
- JNE CHECK_DONE
- MOV IS_THERE_FILE,1 ;SAY YES
- CHECK_DONE: INC SI
- CMP SI,OFFSET INPUT_DIR+LGTH_DIR
- JAE PARA_LOOP_END
- JMP SHORT PARA_LOOP
- PARA_LOOP_END:
- MOV BYTE PTR [SI],0 ;Convert parameter to ASCIIZ.
- CMP IS_THERE_FILE,0 ;IS THERE A FILE PARAMETER
- JE GET_WORKING
- MOV SI,SAVE_LAST_SLASH
- MOV BYTE PTR [SI],0 ;Convert parameter to ASCIIZ.
- INC SI
- MOV DI,OFFSET STAR_DOT_STAR
- MOV CX,12 ;MAX FILE LGTH
- REP MOVSB
- MOV BYTE PTR [DI],0 ;Convert parameter to ASCIIZ.
-
- GET_WORKING: CALL READ_DIR ;PUT DIR STUFF IN MEMORY
- MOV SI,OFFSET VIEW_DIR ;Get current directory.
- CALL GET_DIR
- CMP PURGE_DIR+3 W,"WD" ;DW?? DIR DISPLAYWRITE
- JNZ GET_KEY ;NO
- CALL EBCDIC ;TURN EBCDIC ON
-
- ;-----------------------------------------;
- ; We are ready for business now. We will ;
- ; loop here, waiting for user key strokes.;
- ;-----------------------------------------;
-
- GET_KEY: CALL UPDATE_SCREEN
- CALL READ_KEY ;Get a keystroke.
- MOV BX,AX ;Save returned key.
- CMP AH,1 ;Is it Esc or below?
- JBE FUNCTION ;If yes, function.
- CMP AH,36H ;Is it right shift or above?
- JAE FUNCTION ;If yes, function.
-
- CMP AH,1CH ;Is it CR?
- JZ FUNCTION ;If yes, function.
- MOV AH,2 ;Get shift state.
- INT 16H
- TEST AL,4 ;Is Ctrl depressed?
- JNZ FUNCTION ;If no, check function request.
- CALL SEARCH ;Else, search for first letter.
- JMP SHORT GET_KEY
-
- FUNCTION:
- CMP DEFAULT_MENU,2
- JE FUNCTION2
- MOV DI,OFFSET DISPATCH_KEY
-
- MOV AL,BH
- MOV CX,DISPATCH_CNT ;Valid commands.
- REPNZ SCASB
- JNZ GET_KEY ;If no match, get another.
- MOV DI,OFFSET DISPATCH_END
- JMP FUNCTION_EXE
-
- FUNCTION2:
- MOV DI,OFFSET DISPATCH_KEY2
-
- MOV AL,BH
- MOV CX,DISPATCH_CNT2 ;Valid commands.
- REPNZ SCASB
- JNZ GET_KEY ;If no match, get another.
- MOV DI,OFFSET DISPATCH_END2
-
- FUNCTION_EXE: SHL CX,1
-
- SUB DI,CX
- CALL DS:[DI] ;Else do subroutine.
- JMP SHORT GET_KEY ;Update screen; get next command.
-
- ;*************;
- ; SUBROUTINES ;
- ;*************;
-
- TO_MENU: RET
- NO_OP: RET
-
- ;------------------------------------------------------------------------;
- ; This subroutine CHANGES THE DEFAULT MENU FROM SHORT TO LONG ;
- ;------------------------------------------------------------------------;
-
- NEW_MENU:
- MOV DEFAULT_MENU,1 ;DEFAULT TO LONG MENU
- CALL REFRESH_MENU ;AND DISPLAY IT
- RET
- ;------------------------------------------------------------;
- ; This subroutine does special processing related to the /M3 ;
- ; switch. It will oes special processing related to the /M3 ;
- ;------------------------------------------------------------;
- COPY_MODEL:
- CALL CLEAR_MSG
- CALL COUNT_MARKS ;Count marks.
- CMP CX,1 ;ONE marked file?
- JE COPY_MODEL_DEST ;If yes, display "Copy" message.
- JB COPY_MODEL_DIR
- CALL CLEAR_MSG
- MOV DX,172FH
- MOV SI,OFFSET COPY_MODEL_ERR
- CALL DISPLAY_TEXT
- JMP COPY_MODEL_ERROR ;If yes, exit.
- COPY_MODEL_DIR:
- CALL GET_NAME ;Is the highlighted a directory?
- JNC COPY_MODEL_DEST ;If yes, exit.
- JMP COPY_MODEL_ERROR ;If yes, exit.
- COPY_MODEL_DEST:
- MOV DX,162FH
- MOV SI,OFFSET COPY_MODEL_MSG
- CALL DISPLAY_TEXT
- MOV DX,172FH
- MOV SI,OFFSET COPY_MODEL_MSG2
- CALL DISPLAY_TEXT
- MOV AX," "
- MOV WORD TO_MSG+1,AX ;REMOVE Display " to..."
- CALL DESTINATION ;Ask user for destination.
- JC EXIT_MODEL_COPY ;If Esc pressed, exit.
- MOV DI,OFFSET ENTRY B ;SET INPUT FOR ENVIRONMENT
- MOV AL,'.' ;FIND
- MOV CX,10 ; '.. IF THERE
- REPNZ SCASB
- JNE COPY_MODEL_NO_EXT
- DEC DI
- MOV SI,OFFSET BAK
- MOV CX,4 ;Compare "BAK"
- REPE CMPSB
- JNE COPY_MODEL_EXT
- JMP COPY_MODEL ;GET ANOTHER NAME .BAK NG
- COPY_MODEL_NO_EXT:
- MOV DI,FILE_NAME ;SET FILE NAME FOR COMPARE
- MOV AL,"." ;FIND
- MOV CX,12 ;BINARY 00
- REPNZ SCASB
- DEC DI
- MOV SI,OFFSET BAK
- MOV CX,4 ;Compare "BAK"
- REPE CMPSB
- JNE COPY_MODEL_AST
- JMP COPY_MODEL ;DO AGAIN UNTIL NOT BAK
- COPY_MODEL_AST: MOV DI,OFFSET ENTRY B ;SET INPUT FOR ENVIRONMENT
- MOV AL,00 ;FIND
- MOV CX,10 ;BINARY 00
- REPNZ SCASB
- DEC DI
- MOV BYTE PTR [DI],"."
- INC DI
- MOV BYTE PTR [DI],"*"
- COPY_MODEL_EXT:
- MOV AX,"to"
- MOV WORD TO_MSG+1,AX ;restore Display " to..."
- MOV COPY_FLAG,1 ;Else, indicate copy.
- MOV ERROR_EXEC,0 ;SAY NO ERRORS
- CALL EXEC_MARKED ;Execute the command.
- CMP ERROR_EXEC,0 ;SAY NO ERRORS
- JNE EXIT_MODEL_COPY
- MOV COPY_FLAG,0 ;Restore copy flag.
- MOV SI,OFFSET TARGET B ;SET INPUT FOR ENVIRONMENT
- JMP SELECT_MOVE ;GO TO MOVE AND END
- EXIT_MODEL_COPY:
- CALL READ_DIR ;PUT DIR STUFF IN MEMORY
- RET
-
- COPY_MODEL_ERROR:
- CALL BEEP
- RET
-
- ;----------------------------------------------------------------------;
- ; This subroutine selects the highlighted file for processing. The type;
- ;of processing is determined by the function being performed. If an ;
- ;output drive or directory is entered the files selected are copied to ;
- ;that drive or directory. Switch /M3 changes the function of the F2 key;
- ;from sort directory to copy file to new name and put the name into the;
- ;environment. This routine will also look for special file name ;
- ;"MODEL.???" and copy that file to a new name then put that name in the;
- ;environment. The purpose of these last 2 functions is to provide a ;
- ;facility which will allow SuperProject to startup using a an existing ;
- ;project or a model project. ;
- ;----------------------------------------------------------------------;
-
- SELECT:
- CMP OUTPUT_DIR,00 ;WAS THERE AN OUTPUT ENTERE
- JE SELECT_ONLY ;IF NOT JUST SELECT
- JMP COPY ;ELSE DO COPY FUNCITON
- SELECT_ONLY: CALL GET_NAME ;Get the file name.
- JC SELECT_ERROR ;If directory, skip.
- CMP MENU_TYPE,"3" ;/m3
- JNE SELECT_F_NAME
- MOV SI,OFFSET MODEL
- MOV DI,FILE_NAME
- MOV CX,5 ;Compare "MODEL"
- REPE CMPSB
- JNE SELECT_BAK
- JMP COPY_MODEL ;If above, swap.
- SELECT_BAK: MOV DI,FILE_NAME ;SET FILE NAME FOR COMPARE
- MOV AL,"." ;FIND
- MOV CX,12 ;BINARY 00
- REPNZ SCASB
- JNZ SELECT_F_NAME
- DEC DI
- MOV SI,OFFSET BAK
- MOV CX,4 ;Compare "BAK"
- REPE CMPSB
- JNE SELECT_F_NAME
- JMP COPY_MODEL ;If above, swap.
- SELECT_F_NAME: MOV SI,FILE_NAME
- SELECT_MOVE: MOV DI,OFFSET SET_ENV_NAME
- MOV CX,13 ;13 characters MAX
- SELECT_LOOP: LODSB
- STOSB
- CMP AL,00
- JZ SELECT_SET_ENV
- LOOP SELECT_LOOP
- SELECT_SET_ENV:
- MOV CX,OFFSET SET_ENV_LGTH ;FIND ENV SET LGTH
- MOV AX,DI
- SUB AX,CX ;
- DEC AX ;-1
- DEC AX ;-1
- MOV SET_ENV_LGTH,AL ; SET LGTH OF ENV STING
- MOV SI,offset SET_ENV_LGTH ;address of set string
- CALL ENV_SET ;change environment per ds:si
- MOV AX,4D00H ;Get Return Code
- INT 21H
- MOV DI,OFFSET TEMPUS_RETCODE ;Load Return Code Addr
-
- STOSB
- JMP TERMINATE
- SELECT_ERROR:
- CALL BEEP
- RET
-
-
- ;------------------------------------------------------------;
- ; This subroutine displays the highlighted file for viewing. ;
- ;------------------------------------------------------------;
- ;=======================================================================
- VIEW:
- PUSH BP ;Get the file name.
- MOV PAGES,BP_STACK
- CALL GET_NAME ;Get the file name.
- MOV DX,OFFSET SOURCE B ;Open the file.
- MOV AX,3D00H
- INT 21H
- MOV FILE_HANDLE,AX ;Save filehandle.
-
- CALL FIRST_READ
- MOV LAST_PAGE,OFFSET FILE_BUFFER+SIXTEEN_K
- MOV BP,PAGES ;Initialize page pointer.
- MOV ROW,0 ;And row pointer.
- CALL CLS_TEXT ;Clear screen.
-
- GET_VIEW: MOV SI,LAST_PAGE ;Get top of current page.
- MOV BH,ROW ;Get row offset into page.
- CMP BH,0 ;Is it row zero?
- JZ NEXT_VIEW ;If yes, skip.
- MOV DISPLAY_FLAG,0 ;No display.
- PAGE_OFFSET: CALL LINES
- DEC BH
- JNZ PAGE_OFFSET
-
- NEXT_VIEW: MOV BH,25 ;Now display 25 lines.
- XOR DI,DI ;Start at top left corner.
-
- MOV DISPLAY_FLAG,1 ;Display.
- VIEW_DISPLAY: CALL LINES
- DEC BH
- JNZ VIEW_DISPLAY
-
- VIEW_COMMAND: CALL READ_KEY ;Get a keystroke.
- MOV AL,AH ;Save returned key.
- CMP AL,K_ESC ;Is it Esc?
- JZ VIEW_END ;If yes, exit view.
- CMP AL,K_ENTER ;Is it carriage return?
- JZ VIEW_END ;If yes, exit view.
- CMP AL,K_F3 ;Is it F3?
- JZ VIEW_END ;If yes, exit.
- ;------------------FW CHANGE------------------------------------------
- GET_DISPATCH: MOV DI,OFFSET VIEW_KEY
- MOV AL,AH
- MOV CX,VIEW_CNT ;Valid commands.
- REPNZ SCASB
- JNZ VIEW_COMMAND ;If no match, get another.
- MOV DI,OFFSET VIEW_TABLE_END
-
- SHL CX,1
- SUB DI,CX
- CALL DS:[DI] ;Else do subroutine.
- JC VIEW_COMMAND ;Carry indicates no screen update.
- JMP GET_VIEW ;Update screen; get next command.
- ;---------------------------------------------------------------------
- VIEW_END: MOV BX,FILE_HANDLE ;Close the file.
- MOV AH,3EH
- INT 21H
- CALL CLS
- CALL REFRESH_DIR ;Restore menu.
- POP BP
- RET
-
- VIEW_REQUEST: CALL VIEW_END ;If request of another function,
- CALL UPDATE_SCREEN ; close file and update screen.
- POP BP
- RET
-
- ;----------------------------------------------------------------------;
- ; These six subroutines control the page and starting row of the view. ;
- ;----------------------------------------------------------------------;
- UP_LINE: CMP ROW,0 ;Are we at row zero?
- JNZ DEC_ROW ;If no, decrement one row.
- CMP BP,PAGES ;Else, are we at first page?
- STC
- JZ UP_LINE_END ;If yes, no change.
- CALL UP_PG ;Else, move up one page.
- MOV ROW,25 ;And move starting row to 25
- DEC_ROW: DEC ROW ;Decrement row.
- CLC ;Flag to update screen.
- UP_LINE_END: RET
-
- DN_LINE: CALL CK_FILE_END ;Are we at end of file?
- JNC CK_ROW ;If no, check row.
- RET ;Else, return.
- CK_ROW: CMP ROW,24 ;Are we at last row?
- JB INC_ROW ;If no, increment row.
- CALL DN_PG ;Else, page down.
- MOV ROW,-1 ;And move row to top.
- INC_ROW: INC ROW
- CLC
- DN_LINE_END: RET
-
- UP_PG: CMP BP,PAGES ;Are we already at first page?
- JNZ DEC_PG ;If no, decrement page.
- CMP ROW,0 ;Are we at first row?
- STC
- JZ UP_PG_END ;If yes, no update.
- MOV ROW,0 ;Else move to first row.
- JMP SHORT UPDATE_PAGE
- DEC_PG: MOV SI,LAST_PAGE ;Get current page.
- SUB SI,DS:[BP] ;Subtract difference to prev page.
- CMP SI,OFFSET FILE_BUFFER ;Beyond top of buffer?
- JAE UP_PG_RET ;If no, page up.
- CALL BACKWARD ;Else, read in previous 16K
- JMP SHORT DEC_PG ;Try again.
- UP_PG_RET: DEC BP
- DEC BP ;Decrement page pointer.
- MOV LAST_PAGE,SI ;Store new starting position
- UPDATE_PAGE: CLC
- UP_PG_END: RET
-
- DN_PG: CMP BP,FILE_BUFFER ;Out of room for page storage?
- JAE NOUPDATE_PG ;If yes, skip.
- MOV SI,LAST_PAGE ;Else, retrieve current page
- MOV DISPLAY_FLAG,0 ;No display.
- MOV BH,25 ;Move up 25 lines.
- NEXT_PAGE: CALL LINES
- DEC BH
- JNZ NEXT_PAGE
- CALL CK_FILE_END ;End of file?
- JC NOUPDATE_PG ;If yes, no update.
- INC_PG: MOV DX,LAST_PAGE ;Else, save current offset.
- MOV LAST_PAGE,SI ;Store new offset.
- MOV AX,SI
- SUB AX,DX ;Get difference between pages.
- INC BP ;Increment page storage.
- INC BP
- MOV DS:[BP],AX ;And store.
- CLC
- DN_PG_END: RET
- NOUPDATE_PG: STC
- RET
-
- HOME_FILE: CALL UP_PG ;Page up until top of file.
- JNC HOME_FILE
- CLC
- RET
-
- END_FILE: CALL DN_PG ;Page down until end of file
- JNC END_FILE
- CLC
- RET
-
- ;----------------------------------------------------------------;
- ; This subroutine checks to see if end of file has been reached. ;
- ;----------------------------------------------------------------;
-
- CK_FILE_END: CMP SI,FILE_END
- JB NOT_FILE_END
- CMP FILE_END,OFFSET FILE_BUFFER+(SIXTEEN_K * 2)
- JAE NOT_FILE_END
- STC
- RET
- NOT_FILE_END: CLC
- RET
-
- ;----------------------------------------------------------------;
- ; This subroutine formats the text into lines. A line is marked ;
- ; by either a carriage return or reaching the last column (80). ;
- ;----------------------------------------------------------------;
-
- LINES: MOV CX,80 ;80 COLUMES
- NEXT_LINES: CMP SI,FILE_END ;If end of file, pad with spaces.
- JB GET_LINES
- CMP FILE_END,OFFSET FILE_BUFFER+ (SIXTEEN_K * 2)
- JB PAD_SPACES
- PUSH BX ;If end of buffer, save
- PUSH CX ; our pointers and
- PUSH DI ; read next 16K.
- CALL FORWARD
- POP DI ;Restore pointers.
- POP CX
- POP BX
-
- GET_LINES: LODSB ;Get a byte.
- CMP EBCDIC_FLAG,1 ;EBCDIC ON
- JNE NOT_EBCDIC ;NO
- CALL_EBCDIC: CALL EBCDIC_TRANS
- NOT_EBCDIC: AND AL,WORDSTAR_BIT ;Strip high bit for WordStar?
- CMP AL,13 ;Carriage return?
- JZ PAD_SPACES ;If yes, pad balance of line
- CMP AL,9 ;Is it tab character?
- JZ TAB ;If yes, tab.
- CMP AL,10 ;Is it linefeed?
- JZ NEXT_LINES ;If yes, skip.
- PUSH CX ;Save counter.
- MOV CX,1 ;Else, display one character
- CALL CK_DISPLAY
- POP CX
- NEXT_BYTES: LOOP NEXT_LINES ;Get next byte.
- CMP BYTE PTR [SI],13 ;Is this a eighty column line?
- JNZ END_LINES ;If no, skip.
- INC SI ;Else, bump pointer past CR.
- END_LINES: RET
-
- TAB: PUSH CX ;Save counter.
- DEC CX ;Adjust column counter.
- AND CX,7 ;Get bottom three bits.
- INC CX ;Adjust.
- PUSH CX
- CALL PAD_SPACES ;Move to next tab position.
- POP AX
- POP CX
- SUB CX,AX ;Adjust counter.
- JNZ NEXT_LINES ;Next byte if not column 80.
- RET
-
- PAD_SPACES: MOV AL,32 ;Space character.
- CK_DISPLAY: CMP DISPLAY_FLAG,1 ;Are we to write it to screen?
- JNZ CK_DISP_END ;If no, return.
- MOV BL,AL
- WRITE_VIEW: CALL WRITE_SCREEN ;Else, write CX spaces.
- LOOP WRITE_VIEW
- CK_DISP_END: RET
-
- ;-------------------------------------------------------------------;
- ; These two subroutines read either the next or previous 16K bytes. ;
- ;-------------------------------------------------------------------;
-
- FORWARD: SUB LAST_PAGE,SIXTEEN_K ;Adjust current page offset.
- XOR CX,CX ;Move file pointer
- MOV DX,SIXTEEN_K ; forward 16K.
- CALL MOVE_POINTER
- FIRST_READ: MOV SI,OFFSET FILE_BUFFER+SIXTEEN_K
- MOV DI,OFFSET FILE_BUFFER ;Move second half of buffer
- CALL MOVE_BUFFER ; to first half and read 16K
- MOV CX,-1 ;Move file pointer back.
- NEG DX
- CALL MOVE_POINTER
- RET
-
- BACKWARD: ADD LAST_PAGE,SIXTEEN_K ;Adjust current page offset.
- MOV CX,-1 ;Move pointer back 32K.
- MOV DX,- (SIXTEEN_K * 2)
- CALL MOVE_POINTER
- MOV SI,OFFSET FILE_BUFFER ;Move first half of
- MOV DI,OFFSET FILE_BUFFER+SIXTEEN_K ; buffer to second
- CALL MOVE_BUFFER ; and read 16K.
- RET
-
- MOVE_POINTER: MOV BX,FILE_HANDLE
- MOV AX,4201H ;Move file pointer.
- INT 21H
- RET
-
- MOVE_BUFFER: MOV DX,SI ;Save pointer.
- MOV CX,SIXTEEN_K / 2 ;Move 8K words (16K bytes).
- REP MOVSW
- MOV BX,FILE_HANDLE
- MOV CX,SIXTEEN_K ;Read 16K.
- MOV AH,3FH
- INT 21H
- MOV SI,DX
- MOV DX,AX
- ADD AX,OFFSET FILE_BUFFER+SIXTEEN_K
- MOV FILE_END,AX ;Store end of buffer offset.
- RET
- ;=======================================================================
-
- EBCDIC_TRANS: PUSH SI
- MOV SI,OFFSET EBCDIC_TR ;LOAD ADDR OF TABLE
- MOV AH,0 ;NEW CHARACTER
- ADD SI,AX ;ADD CHAR TO ADDR
- MOV AL,BYTE PTR[SI] ;NEW CHARACTER
- POP SI
- RET
-
- ;---------------------------------------------------;
- ; This subroutine renames the HIGHLIGHED FILES ;
- ;---------------------------------------------------;
- RENAME: MOV RENAME_FILE_FLAG,1 ;TURN RENAME ON
- CALL CLEAR_MSG
- CALL MOVE ;MOVE AND RENAME SAME
- MOV RENAME_FILE_FLAG,0 ;TURN RENAME OFF
- RET
-
- ;---------------------------------------------------------------;
- ; This subroutine copies either the highlighted or marked file. ;
- ;---------------------------------------------------------------;
- COPY: CALL COUNT_MARKS ;Count marks.
- CMP CX,0 ;Any marked files?
- JNZ COPY_DEST ;If yes, display "Copy" message.
- CALL GET_NAME ;Is the highlighted a directory?
- JC COPY_ERROR ;If yes, exit.
- COPY_DEST: MOV DX,172FH
- MOV SI,OFFSET COPY_MSG
- CALL DISPLAY_TEXT
- CALL DESTINATION ;Ask user for destination.
- JC EXIT_COPY ;If Esc pressed, exit.
- MOV COPY_FLAG,1 ;Else, indicate copy.
- CALL EXEC_MARKED ;Execute the command.
- MOV COPY_FLAG,0 ;Restore copy flag.
- END_COPY: MOV TEMPUS_RETCODE,0 ;SET RETURN CODE
- CMP OUTPUT_DIR,00 ;WAS THERE AN OUTPUT ENTERE
- JE EXIT_COPY ;IF NOT EXIT
- JMP TERMINATE ;EXIT TO RN
- EXIT_COPY: CALL READ_DIR ;PUT DIR STUFF IN MEMORY
- RET
-
- COPY_ERROR:
- MOV TEMPUS_RETCODE,4 ;SET RETURN CODE
- CALL BEEP
- RET
-
- ;----------------------------------------------------------------;
- ; This subroutine deletes either the highlighted or marked file. ;
- ;----------------------------------------------------------------;
-
- DELETE: MOV DX,172FH ;Postion cursor for display.
- CALL SET_CURSOR
- CALL COUNT_MARKS ;Get count of marked files.
- CMP CX,0 ;Any marked?
- JNZ DELETE_MARKED ;If marked, display number marked.
- CALL GET_NAME ;Else get highlighted.
- JC DELETE_ERROR ;If it's a directory exit.
- CMP BYTE PTR [SI+39],"H" ;If it's a hidden file exit.
- JZ DELETE_ERROR
- MOV SI,FILE_NAME ;Else display filename.
- JMP SHORT DISP_DELETE
-
- DELETE_MARKED: MOV AX,CX ;Display count of marked files.
- CALL GET_COUNT
- MOV SI,OFFSET MARKED_MSG ;Display "marked files".
- DISP_DELETE: CALL GET_TEXT
- MOV SI,OFFSET DELETE_MSG ;Display "will be deleted".
- CALL GET_TEXT
- MOV DX,182FH ;Display warning message.
- CALL DISPLAY_TEXT
-
- QUERY: CALL READ_KEY ;Get a keystroke.
- CMP AH,31H ;Is it "N"?
- JZ DELETE_END ;If yes, exit delete.
- CMP AH,1 ;Is it Esc?
- JZ DELETE_END ;If yes, exit delete.
- CMP AH,15H ;Is it "Y"?
- JZ DELETE_FILE ;If yes, delete
- CALL BEEP ;Else, beep.
- JMP SHORT QUERY ;And get another keystroke.
-
- DELETE_FILE: MOV DELETE_FLAG,1 ;Indicate deletion.
- CALL EXEC_MARKED ;Execute the command.
- MOV DELETE_FLAG,0 ;Restore deletion flag.
- DELETE_END: CALL CLEAR_MSG
- RET
-
- DELETE_ERROR: CALL BEEP ;Beep if error.
- RET
-
- ;--------------------------------------------------------------;
- ; This subroutine moves either the highlighted or mark ed file.;
- ;--------------------------------------------------------------;
-
- MOVE: CALL COUNT_MARKS ;Get count of marked files.
- CMP CX,0 ;Any files marked?
- JNZ MOVE_DEST ;If yes, display message.
- CALL GET_NAME ;Else, see if highlighted is a
- JC MOVE_ERROR ; directory; If yes, exit.
- MOVE_DEST: MOV DX,172FH
- MOV SI,OFFSET MOVE_MSG ;Display move message.
- CMP RENAME_FILE_FLAG,1
- JNZ MOVE_MSG_WRIT
- MOV SI,OFFSET RENAME_MSG ;Display RENAME MESSAGE
- MOVE_MSG_WRIT: CALL DISPLAY_TEXT
- CALL DESTINATION ;Get user response.
- JC END_MOVE ;If Esc pressed, exit.
- MOV AL,CURRENT_DISK ;Else, check if move across drives.
- ADD AL,"A" ;Get default drive.
- CMP BYTE PTR ENTRY B + 1,":" ;Is there a drive specified?
- JNZ CK_DRIVE ;If not, use default.
- MOV AL,ENTRY B ;Else, use user drive.
- AND AL,5FH ;Capitalize.
- CK_DRIVE: CMP AL,SOURCE B ;Is it the same as source?
- JZ JUST_RENAME ;If yes, rename.
- COPY_DELETE: MOV COPY_FLAG,1 ;Else, indicate both copy/delete.
- MOV DELETE_FLAG,1
- JUST_RENAME: MOV RENAME_FLAG,1
- EXEC_MOVE: CALL EXEC_MARKED ;Execute the command.
- END_MOVE: MOV DELETE_FLAG,0 ;Restore all flags.
- MOV COPY_FLAG,0
- CMP RENAME_FLAG,1
- JNE NO_REREAD
- NO_REREAD: MOV RENAME_FLAG,0
- MOV TEMPUS_RETCODE,0 ;SET RETURN CODE
- CMP OUTPUT_DIR,00 ;WAS THERE AN OUTPUT ENTEREd
- JE EXIT_MOVE ;IF NOT EXIT
- JMP TERMINATE ;EXIT TO RN
- EXIT_MOVE: CALL READ_DIR ;PUT DIR STUFF IN MEMORY
- RET
-
- MOVE_ERROR: MOV TEMPUS_RETCODE,4 ;SET RETURN CODE
- CALL BEEP
- RET
-
- ;-----------------------------------;
- ; This subroutine clears all marks. ;
- ;-----------------------------------;
-
- CLEAR_MARK: MOV SI,OFFSET BUFFER ;Point to start of listing.
- NEXT_CLEAR: MOV BYTE PTR [SI],32 ;Write space over mark.
- ADD SI,FIELD_SIZE ;Next record.
- CMP SI,END_OFFSET ;End of listing?
- JB NEXT_CLEAR ;If no, continue until done.
- RET
- ;----------------------------------------------------------------------;
- ; This subroutine marks all files that aren't marked with an asterisk. ;
- ;----------------------------------------------------------------------;
-
- MARK_BLANK: MOV SI,OFFSET BUFFER ;Point to start of listing.
- NEXT_BLANK: CMP BYTE PTR [SI+14],"<" ;Is it a directory?
- JZ LOOP_MARK ;If yes, skip.
- CMP BYTE PTR [SI+40],"H" ;Is it a hidden file?
- JZ LOOP_MARK ;If yes, skip.
- CMP BYTE PTR [SI],32 ;Is it blank (a space)?
- JNZ LOOP_MARK ;If no, skip.
- MOV BYTE PTR [SI],COPY_MARK ;Else mark.
- LOOP_MARK: ADD SI,FIELD_SIZE ;Next record.
- CMP SI,END_OFFSET ;Continue until done.
- JB NEXT_BLANK
- RET
-
- ;--------------------------------------------------------;
- ; This subroutine marks or unmarks the highlighted file. ;
- ;--------------------------------------------------------;
- MARK_UNMARK: MOV DL,"?" ;SPECIAL MARK
- JMP SHORT STORE_MARK
-
- MARK: MOV DL,COPY_MARK ;Right arrow character.
- JMP SHORT STORE_MARK
-
- UNMARK: MOV DL,32 ;Space character.
-
- STORE_MARK: CALL GET_NAME ;Get filename.
- JC MARK_END ;If directory, skip.
- CMP BYTE PTR [SI+39],"H" ;Is it a hidden file?
- JZ MARK_END ;If yes, skip.
- CMP DL,"?" ;IS IT ? FOR ON/OFF
- JNZ SHORT MARK_ON_OFF ;NOT = GO DO MARK
- CMP BYTE PTR [SI-1],COPY_MARK ;IS IT MARKED
- JNZ MARK_ONE ;NO GO MARK IT
- MOV BYTE PTR [SI-1],32 ;TURN MARK OFF
- JMP SHORT MARK_END ;TO END
- MARK_ONE: MOV BYTE PTR [SI-1],COPY_MARK ;MARK IT
- JMP SHORT MARK_END ;TO END
- MARK_ON_OFF: MOV [SI-1],DL ;Else store the character.
- MARK_END: CALL DN_ARROW2 ;And move down a row.
- RET
- ;------------------------------------------------;
- ; This subroutine toggles the copy verify state. ;
- ;------------------------------------------------;
-
- VERIFY: XOR VERIFY_FLAG,1 ;Toggle flag.
- MOV AL,1 ;ASSUME ON
- MOV SI,OFFSET VERIFY_ON B
- MOV BYTE PTR [SI],251
-
- CMP VERIFY_FLAG,1 ;Is it on?
- JZ TOGGLE ;If yes, store.
- XOR AL,AL
- MOV BYTE PTR [SI],32
-
- TOGGLE: CALL SET_VERIFY
- CALL REFRESH_MENU ;Display.
- RET
- ;------------------------------------------------;
- ; This subroutine toggles to EBCDIC mode. ;
- ;------------------------------------------------;
-
- EBCDIC: XOR EBCDIC_FLAG,1 ;Toggle flag.
- MOV SI,OFFSET EBCDIC_ON B
- MOV BYTE PTR [SI],251 ;ASSUME ON
- CMP EBCDIC_FLAG,1 ;Is it on?
- JE EBCDIC_TOGGLE
- MOV BYTE PTR [SI],32 ;TURNMOFFN
- EBCDIC_TOGGLE: CALL REFRESH_MENU ;Display.
- RET
-
- ;--------------------------------------------------;
- ; This subroutine toggles the toggle wordstar mode ;
- ;--------------------------------------------------;
-
- WORDSTAR: XOR WORDSTAR_BIT,80H ;Toggle flag.
- MOV SI,OFFSET WORDSTAR_ON B
- MOV BYTE PTR [SI],251 ;ASSUME ON
- CMP WORDSTAR_BIT,7FH ;Is it on?
- JE WORDSTAR_TOGGLE ;If yes, store.
- MOV BYTE PTR [SI],32 ;TURN OFF
-
- WORDSTAR_TOGGLE: CALL REFRESH_MENU ;Display.
- RET
- ;----------------------------------------------------;
- ; This subroutine counts the number of marked files. ;
- ;----------------------------------------------------;
-
- COUNT_MARKS: XOR CX,CX ;Zero out counter.
- MOV SI,OFFSET BUFFER ;Point to start of listing.
- NEXT_COPY: CMP BYTE PTR [SI],COPY_MARK ;Is it marked?
- JNZ LOOP_COPY ;In no, skip.
- INC CX ;Else, increment counter.
- LOOP_COPY: ADD SI,FIELD_SIZE ;Next record.
- CMP SI,END_OFFSET ;Continue until done.
- JB NEXT_COPY
- MOV MARK_CNT,CX ;Store the count of marked files.
- RET
-
- ;---------------------------------------------;
- ; This subroutine prompts the user for the ;
- ; destination of highlighted or marked files. ;
- ;---------------------------------------------;
-
- DESTINATION: CALL GET_NAME ;Get filename.
- MOV SI,FILE_NAME
- MOV AX,MARK_CNT ;Retrieve count of marked files.
- CMP AX,0 ;Were there any?
- JZ DISP_SOURCE ;If no, display source filename.
- CALL GET_COUNT ;Else, display count of marked.
- MOV SI,OFFSET MARKED_MSG ;Display "marked files".
- DISP_SOURCE: CALL GET_TEXT
- ;-----------------------FW CHANGE-------------------------------------
- CMP OUTPUT_DIR,00 ;WAS THERE AN OUTPUT ENTEREd
- JZ COPY_DO_MSG
- CALL CLEAR_OLD ;CLEAR LAST ENTRY
- MOV SI,OFFSET OUTPUT_DIR
- MOV DI,OFFSET ENTRY B ;Write OUTPUT DIR
- XOR AX,AX
- MOV CX,LGTH_DIR
- REP MOVSB
- JMP DO_DEST ;If yes, execute.
- COPY_DO_MSG: MOV SI,OFFSET TO_MSG ;Display "to..."
- ;---------------=-----------------------------------------------------
- CALL GET_TEXT
- MOV DX,182FH
- CALL CLEAR_OLD ;Remove last user entry.
-
- GET_DEST: CALL READ_KEY ;Get a keystroke.
- CMP AL,27 ;Is it Esc?
- JZ ABORT_DEST ;If yes, abort.
- CMP AL,13 ;Is it carriage return?
- JZ DO_DEST ;If yes, execute.
- CMP AL,8 ;Is it backspace?
- JNZ NOT_BS3 ;If yes, backspace.
- CALL MOVE_BS
- JMP SHORT GET_DEST
- NOT_BS3: CMP AL,32 ;Is it above space?
- JBE GET_DEST ;If no, ignore.
- CMP DI,OFFSET ENTRY B + 32 ;Else, is 32 line entry field full?
- JZ GET_DEST ;If yes, ignore.
- STOSB ;Else, store the character.
- CALL WRITE_TEXT ;And display it.
- JMP SHORT GET_DEST
- ABORT_DEST: CALL CURSOR_OFF
- CALL CLEAR_MSG
- STC
- RET
-
- DO_DEST: CLC
- RET
-
- ;------------------------------------------------------------------------------;
- ; This subroutine either copies moves or deletes a highlighted or marked file. ;
- ;------------------------------------------------------------------------------;
-
- EXEC_MARKED:
- CLC
- CALL CURSOR_OFF ;Turn cursor off.
- CMP MARK_CNT,0 ;Are there any files marked?
- JNZ MANY_MARKS ;If yes, go find them.
- MOV MARK_CNT,1 ;Else, change loop counter to one.
- CALL GET_NAME
- JMP SHORT EXEC_BAR ;And execute it one time.
-
- MANY_MARKS: CALL HOME_BAR ;Home the highlight bar.
- CK_MARK: CALL UPDATE_SCREEN ;Update the screen.
- CALL GET_NAME ;Get the highlighted filename.
- CMP BYTE PTR [SI-1],COPY_MARK ;Is it marked?
- JZ EXEC_BAR ;If yes, execute command
- CALL DN_ARROW2 ;Else, move down a row.
- JMP SHORT CK_MARK ;And check it for a mark.
-
- EXEC_BAR: CMP BYTE PTR [SI+39],"H" ;Is it a hidden file?
- JZ EXEC_ERROR ;If yes, skip.
- CMP RENAME_FLAG,1 ;Is it a same drive move?
- JNZ CK_COPY ;If no, skip renaming.
- CALL PARSE_ENTRY ;Else, parse user entry.
- MOV DX,OFFSET TARGET ;Point to target.
- MOV CX,7 ;Does the file exist?
- CALL FIND_FIRST
- JNC EXEC_ERROR ;If yes, skip
- CMP COPY_FLAG,1 ;Is it across drives?
- JZ GO_READ_WRITE ;Is yes copy/delete.
- MOV DX,OFFSET SOURCE B
- MOV DI,OFFSET TARGET
- MOV AH,56H ;Else, rename it.
- INT 21H
- JC EXEC_ERROR ;Next one if failed.
- JMP SHORT REMOVE ;Else, remove it from list.
-
- CK_COPY: CMP COPY_FLAG,1 ;Is it a copy request?
- JNZ CK_DELETE ;If no, check delete.
- CALL PARSE_ENTRY ;Else parse user entry.
- GO_READ_WRITE: CALL READ_WRITE ;Copy the file.
- JC EXEC_ERROR ;If failed, skip rest.
- MARK_IT: MOV SI,CUR_FILE ;Else, mark with PERIOD
- MOV BYTE PTR [SI-1],COPY_MARK_DONE
- CK_DELETE: CMP DELETE_FLAG,1 ;Is it a delete request?
- JNZ CK_KEYSTROKE ;If no, skip.
- MOV DX,OFFSET SOURCE B ;Else, delete the file.
- MOV AH,41H
- INT 21H
- JC EXEC_ERROR
- REMOVE: CALL REMOVE_FILE ;If successful, remove from list.
- JMP SHORT CK_KEYSTROKE
-
- EXEC_ERROR: CALL BEEP
- MOV ERROR_EXEC,1
- CALL DN_ARROW2 ;Go to next line.
-
- CK_KEYSTROKE: CALL CK_KEY ;Was a key struck while busy
- JNZ CLEAR_KEY ; at our copy, move or delete task?
- DEC MARK_CNT ;If yes, abort, else all done?
- JZ END_EXEC ;If no, continue until done.
- JMP CK_MARK
-
- CLEAR_KEY: CALL READ_KEY ;Clear the keyboard buffer,
- CALL CK_KEY ; user entry and prompt.
- JNZ CLEAR_KEY
- END_EXEC: CALL UPDATE_FREE
- CALL FILE_COUNT
- CALL CLEAR_MSG
- RET
-
- ;----------------------------------------;
- ; This subroutine parses the user entry. ;
- ;----------------------------------------;
-
- PARSE_ENTRY: MOV BP,OFFSET TARGET ;Point to target storage.
- MOV DI,BP
- MOV SI,OFFSET ENTRY B ;Point to user entry.
- CMP BYTE PTR [SI],0 ;Anything entered?
- JNZ GET_END ;If yes, continue.
- JMP TACK_FILENAME ;Else, store source name.
-
- GET_END: LODSB ;Move user entry into target
- STOSB ; workspace.
- CMP AL,0
- JNZ GET_END
-
- STD ;Reverse string operation.
- DEC DI ;Adjust pointer back one.
- MOV SI,DI ;Make it the source pointer.
- MOV FILENAME_END,DI ;And store.
- FIND_PATH: CMP SI,OFFSET TARGET - 1 ;Are we at start of name?
- JZ SEARCH_WILD ;If yes, done here.
- LODSB
- CMP AL,"\" ;Else, is it a path delimiter?
- JZ FOUND_PATH ;If yes, mark start of filename.
- CMP AL,":" ;Colon is also a path delimiter.
- JNZ FIND_PATH
-
- FOUND_PATH: INC SI ;Adjust pointer to end of path.
- SEARCH_WILD: INC SI
- MOV BP,SI ;And store.
- CLD ;String back to forward.
- MOV DI,FCB ;Use file control block for
- MOV AX,2900H ; workspace.
- INT 21H ;Parse the entry for globals.
- CMP AL,1 ;Any wild cards?
- JNZ CK_PATH ;If no, check if it's a directory.
-
- MOV SI,FCB + 1 ;Else, point to first character.
- MOV DI,BP ;Point to target storage.
- MOV BX,FILE_NAME ;Point to source.
- MOV CX,8 ;Eight characters.
- GLOBAL_NAME: LODSB
- CMP AL,32 ;End of name?
- JZ EXTENSION ;If yes, do extension.
- CMP AL,"?" ;Wild card?
- JNZ LOOP_NAME ;If no, store target character.
- MOV AL,[BX] ;Else, replace with source char.
- CMP AL,"." ;Unless end of name.
- JZ EXTENSION
- CMP AL,0
- JZ EXTENSION
- LOOP_NAME: STOSB ;Store the character.
- CMP BYTE PTR [BX],"." ;Are we at end of source name?
- JZ NEXT_GLOBAL ;If yes, don't move pointer.
- INC BX ;Else, point to next source char.
- NEXT_GLOBAL: LOOP GLOBAL_NAME
-
- EXTENSION: MOV AL,"." ;Filename delimiter.
- STOSB ;Store it.
- FIND_EXT: CMP [BX],AL ;Was there a dot in source?
- JZ DO_DOT ;If yes do extension.
- CMP BYTE PTR [BX],0 ;End of source name?
- JZ DO_EXT ;If yes, do extension.
- INC BX ;Else, go to end of name.
- JMP SHORT FIND_EXT
-
- DO_DOT: INC BX ;Bump pointer past dot.
- DO_EXT: MOV SI,FCB + 9 ;Point to extension of parsed.
- MOV CX,3 ;Three characters.
- DO_EXTENSION: LODSB
- CMP AL,32 ;End of parsed?
- JZ END_GLOBAL ;If yes, done here.
- CMP AL,"?" ;Wild card?
- JNZ LOOP_EXT ;If no, store user character.
- MOV AL,[BX] ;Else, store source character.
-
- LOOP_EXT: STOSB
- INC BX
- LOOP DO_EXTENSION ;Do all three extension chars.
-
- END_GLOBAL: XOR AL,AL ;Make it an ASCIIZ.
- STOSB
- JMP SHORT PARSE_END ;Done here.
-
- CK_PATH: MOV DI,BP ;Any characters after path
- CMP BP,FILENAME_END ; delimiter?
- JZ TACK_FILENAME ;If no, tack on source name.
- MOV DX,OFFSET ENTRY B ;Else, see if it's a directory.
- MOV CX,10H
- CALL FIND_FIRST
- JC PARSE_END ;If not found, done here.
- CMP DS:[149],CL ;If not directory, done here.
- JNZ PARSE_END
- MOV DI,FILENAME_END ;Else, tack on source filename.
- MOV AL,"\"
- STOSB
-
- TACK_FILENAME: MOV SI,FILE_NAME ;Source filename.
- MOV CX,7
- REP MOVSW
- PARSE_END: RET
-
- ;----------------------------------------------------;
- ; This section does the reading and writing to disk. ;
- ;----------------------------------------------------;
-
- READ_WRITE: MOV DX,OFFSET SOURCE B ;Point to source filespec.
- XOR AL,AL ;Open file for reading.
- CALL OPEN_FILE
- JNC SAVE_HANDLE
- JMP END_RW ;Exit if failed.
- SAVE_HANDLE: MOV READ_HANDLE,AX ;Save the handle.
- MOV CX,7
- CALL FIND_FIRST ;Get source
- MOV SI,149
- LODSB
- XOR AH,AH
- MOV SOURCE_ATTRIB,AX ; attribute
- MOV TARGET_ATTRIB,AX ; attribute
- LODSW
- MOV SOURCE_TIME,AX ; time
- LODSW
- MOV SOURCE_DATE,AX ; date
- LODSW
- MOV SIZE_LOW,AX ; and size
- LODSW
- MOV SIZE_HIGH,AX ; and save.
-
- MOV DX,OFFSET TARGET ;Point to target filename.
- CALL FIND_FIRST ;Does it exist?
- JNC CK_IF_SAME ;If yes, see if same as source.
-
- CALL GET_DISK ;Else, get disk free space.
- JMP SHORT CK_FREE ;Go see if enough room.
-
- CK_IF_SAME: MOV CL,DS:[149] ;Get attribute of target
- XOR CH,CH
- MOV BP,CX ; and save.
- XOR CX,1 ;Flip read-only attribute.
- CALL CHMOD
- MOV DX,OFFSET SOURCE B ;Now get source attribute.
- CALL GETMOD
- CMP CX,SOURCE_ATTRIB ;See if it has changed.
- PUSHF ;Save compare results.
- MOV DX,OFFSET TARGET ;Restore target attribute.
- MOV CX,BP
- CALL CHMOD
- POPF ;Retrieve compare results.
- STC ;Assume files are the same.
- JZ GET_FREE_SPACE
- JMP CLOSE_READ ;If they are, exit.
- GET_FREE_SPACE: CALL GET_DISK ;Else, get free disk space.
- ADD AX,DS:[154]
- ADC DX,DS:[156] ;Target size + disk free.
- CK_FREE: SUB AX,SIZE_LOW ;Total - source size.
- SBB DX,SIZE_HIGH
- JB CLOSE_READ ;If negative, not enough room.
-
- CREATE: MOV DX,OFFSET TARGET ;Create and truncate target file
- XOR CX,CX ; to zero.
- MOV CX,TARGET_ATTRIB ;attribute
- MOV AH,3CH
- INT 21H
- JC CLOSE_READ
- MOV WRITE_HANDLE,AX ;Save handle.
- MOV AX,DS ;Point to second 64K segment
- ADD AX,1000H ; for read/write buffer.
- MOV DS,AX
- XOR DX,DX
-
- COPY_READ: MOV BX,CS:READ_HANDLE ;Retrieve read handle.
- MOV CX,0FFFFH ;Read up to 64K at a time.
- MOV AH,3FH
- INT 21H
- JC COPY_DONE ;If done, exit.
- CMP AX,0 ;If zero, also done.
- JZ CHANGE_DATE
-
- MOV BP,AX ;Save bytes read.
- MOV CX,AX ;Bytes read into counter.
- MOV BX,CS:WRITE_HANDLE ;Retrieve write handle.
- MOV AH,40H
- INT 21H ;Write the buffer to disk.
- JC COPY_DONE
- CMP CX,BP ;Did we write same number as read?
- STC ;Assume we had a problem.
- JNZ COPY_DONE ;If no, exit.
- CMP CX,0FFFFH ;Was it a full 64K read?
- JZ COPY_READ ;If yes, there must be more.
- CHANGE_DATE: MOV BX,CS:WRITE_HANDLE
- MOV CX,CS:SOURCE_TIME ;Else, make time/date same
- MOV DX,CS:SOURCE_DATE ; as source.
- MOV AX,5701H
- INT 21H
-
- COPY_DONE: PUSH CS ;Restore data segment.
- POP DS
-
- CLOSE_WRITE: PUSHF ;Save error if any.
- MOV BX,WRITE_HANDLE ;Close write file.
- CALL CLOSE_FILE
- ;---------------FW MOD--------------------------------------------------
- CMP OUTPUT_DIR,00 ;WAS THERE AN OUTPUT ENTERE
- JE CLOSE_COMP
- XOR CX,CX ; ATTRIBUTE TP 00
- MOV DX,OFFSET TARGET ;POINT AT TARGET
- CALL CHMOD
- ;-----------------------------------------------------------------------
- CLOSE_COMP: POP AX ;Retrieve flags.
- JC CLOSE_READ ;Close successful?
- XCHG AH,AL ;If no, exit with error, else
- SAHF ; retrieve write state.
-
- CLOSE_READ: PUSHF ;Save flags.
- MOV BX,READ_HANDLE ;Close read file.
- CALL CLOSE_FILE ;Return with status of
- POPF ; write file.
- END_RW: RET
-
- ;------------------------------------------------------------------------;
- ; These four subroutines control in which column the sorting will start. ;
- ;------------------------------------------------------------------------;
- SORT_TYPE: MOV DX,162FH ;Postion cursor for display.
- MOV SI,OFFSET SORT_MSG1 ;ENTER
- CALL DISPLAY_TEXT
- MOV DX,172FH ;Display warning message.
- MOV SI,OFFSET SORT_MSG2 ;TYPE OF SORT
- CALL DISPLAY_TEXT
- MOV DX,182FH ;Display warning message.
- CALL SET_CURSOR
-
- CALL READ_KEY ;Get a keystroke.
- MOV SAVE_KEY,AH ;SAVE KEY
- CALL CLEAR_MSG
- MOV AH,SAVE_KEY
- CMP AH,K_N ;Is it "N"AME
- JZ SORT_NAME
- CMP AH,K_E ;Is it "E"XTENSION
- JZ SORT_EXT
- CMP AH,K_S ;Is it "S"IZE
- JZ SORT_SIZE
- CMP AH,K_D ;Is it "D"ATE
- JZ SORT_DATE
- CMP AH,K_T ;Is it "T"IME
- JZ SORT_DATE
- RET
- ;------------------------------------------------------------------------;
-
- SORT_NAME: MOV SORT_OFFSET,0
- JMP SHORT SORT_MSG
-
- SORT_EXT: MOV SORT_OFFSET,4
- JMP SHORT SORT_MSG
-
- SORT_SIZE: MOV SORT_OFFSET,8
- JMP SHORT SORT_MSG
-
- SORT_DATE: MOV SORT_OFFSET,12
- SORT_MSG: MOV DX,1733H
- MOV SI,OFFSET LOADING+12
- CALL DISPLAY_TEXT
-
- ;------------------------------------------;
- ; This subroutine does the actual sorting. ;
- ;------------------------------------------;
-
- SORT: CMP COUNT,1 ;Can't sort one file.
- JZ SORT_RETURN
- MOV DX,END_OFFSET ;End of filenames in DX.
- SUB DX,44
- MOV BP,SORT_OFFSET
- NEXT_PASS: MOV SORT_FLAG,0
- MOV BX,OFFSET BUFFER + 1 ;Point to start of buffer.
-
- NEXT_SORT: MOV SI,BX ;Source and destination.
- ADD SI,SORT_TABLE[BP]
- MOV DI,SI
- ADD DI,FIELD_SIZE
- CMP BP,12 ;Is it special case of date?
- JZ DO_DATE ;If yes, go do it.
- MOV CX,SORT_TABLE[BP+2]
- COMPARE: REPZ CMPSB ;Compare filenames.
- JBE END_SORT ;If already in order, skip.
-
- SWAP: MOV SI,BX ;Else, recover pointers.
- DEC SI
- MOV DI,SI
- ADD DI,FIELD_SIZE
- MOV CX,FIELD_SIZE / 2 ;Exchange the records.
- NEXT_SWAP: MOV AX,[DI]
- MOVSW
- MOV [SI-2],AX
- LOOP NEXT_SWAP
- MOV SORT_FLAG,1 ;Flag that exchange was made.
-
- END_SORT: ADD BX,FIELD_SIZE ;Point to next record.
- CMP BX,DX ;End of top?
- JB NEXT_SORT ;If no, bubble sort next.
- SUB DX,FIELD_SIZE ;Else, move top down one record.
- CMP SORT_FLAG,0 ;Was there exchange made?
- JNZ NEXT_PASS ;If yes, another pass.
- SORT_RETURN: CALL CLEAR_MSG
- CMP SORT_OFFSET,12
- JNE SORT_EXIT
- CALL END_BAR ;GO TO END IF DATE SORT
- SORT_EXIT: RET
-
- DO_DATE: MOV CX,2 ;Compare year first.
- REPZ CMPSB
- JA SWAP ;If above, swap.
- JNZ END_SORT
- SUB SI,8 ;Else, adjust and do month/day.
- SUB DI,8
- MOV CX,5
- REPZ CMPSB
- JA SWAP ;If above, swap.
- JNZ END_SORT
- ADD SI,10 ;Else, adjust and do meridian.
- ADD DI,10
- CMPSB
- JA SWAP ;If above, swap.
- JNZ END_SORT
- SUB SI,6 ;Else, adjust and do time.
- SUB DI,6
- MOV CX,5
- CMP WORD PTR [SI],3231H ;Is it special case "12:"?
- JZ CK_MERIDIAN ;If yes, see if same.
- CMP WORD PTR [DI],3231H ;Is destination "12:"?
- JNZ COMPARE ;If no, normal compare.
- JMP SWAP ;Else, swap.
- CK_MERIDIAN: CMPSW ;Are both "12:"?
- JNZ END_SORT ;If no, next record.
- MOV CX,3 ;Else compare minutes.
- JMP SHORT COMPARE
-
- ;--------------------------------------------------------------------------;
- ; These six subroutines control the bar and page of the directory listing. ;
- ;--------------------------------------------------------------------------;
-
- UP_ARROW:
- ;----------------FW----------------------------------------------
- MOV BX,COUNT
- CMP BX,21
- JA UP_ARROW1
- MOV BX,LINE
- ADD BX,-160 ;Move bar up one line.
- CMP BX,PAGE_START-160 ;START OF LIST \ROOT
- JA UP_ARROW2
- JMP END_BAR
- UP_ARROW1: MOV BX,CUR_OFFSET
- ADD BX,-160 ;Move bar up one line.
- CMP BX,OFFSET BUFFER ;START OF LIST
- JA UP_ARROW2
- MOV BX,LINE
- ADD BX,-160 ;Move bar up one line.
- CMP BX,PAGE_START-160 ;START OF LIST \ROOT
- JA UP_ARROW2
- JMP END_BAR
- UP_ARROW2: MOV BP,-160 ;Move bar up one line.
- JMP SHORT BAR_MOVE
-
- DN_ARROW:
- ;----------------FW----------------------------------------------
- MOV BX,COUNT
- CMP BX,21
- JA DN_ARROW1
- MOV BX,LINE
- ADD BX,160
- CMP BX,PAGE_END ;AT LAST LINE
- JAE HOME_BAR
- JMP DN_ARROW2
-
- DN_ARROW1: MOV BX,CUR_OFFSET
- ADD BX,21*FIELD_SIZE+160
- CMP BX,END_OFFSET ;AT LAST PAGE
- JBE DN_ARROW2
- MOV BX,LINE
- ADD BX,160
- CMP BX,PAGE_END ;AT LAST LINE
- JB DN_ARROW2
- JMP HOME_BAR
- ;----------------------------------------------------------------
- DN_ARROW2: MOV BP,160 ;Move bar down one line.
- BAR_MOVE: CALL SCROLL_BAR
- RET
-
- PG_UP: MOV BP,- FIELD_SIZE * 21 ;Move up 21 lines.
- CALL SCROLL
- JMP SHORT BOTTOM_BAR
-
- PG_DN: MOV BP,FIELD_SIZE * 21 ;Move down 21 lines.
- MOVE_PAGE: CALL SCROLL
- JMP SHORT TOP_BAR ;Move bar to top.
-
- HOME_BAR: MOV CUR_OFFSET,OFFSET BUFFER ;Move listing to beginning.
- TOP_BAR: MOV SI,BAR_START ;And move bar to top.
- CALL MOVE_BAR
- RET
-
- END_BAR: MOV BX,END_OFFSET ;Move listing to last page.
- SUB BX,21 * FIELD_SIZE
- CMP BX,OFFSET BUFFER
- JBE BOTTOM_BAR
- MOV CUR_OFFSET,BX
- BOTTOM_BAR: MOV SI,PAGE_END ;And move bar to bottom.
- SUB SI,160
- CALL MOVE_BAR
- RET
-
- ;------------------------------------------------------------------;
- ; Read all the directory filenames and store as records in buffer. ;
- ;------------------------------------------------------------------;
- READ_DIR: MOV BP,OFFSET INPUT_DIR
- MOV SI,OFFSET WORKING_DIR ;Store working drive directory.
- CALL GET_DIR
- CMP RN_SWITCH,32 ;DID RN CALL
- JNE MESSAGE
- CMP INPUT_DIR+1,":" ;Is there a drive request?
- JNZ SET_DIR ;directory change.
- INC BP ; PAST
- INC BP ; DRIVE
- SET_DIR: CMP BYTE PTR [BP],32 ;Is it a delimiter?
- JBE MESSAGE ;If yes, skip.
- MOV DX,BP ;Retrieve start.
- CALL CHANGE_DIR ;Change directory.
- MOV DX,OFFSET INVALID
- JNC MESSAGE ;If GOOD JUMP
- JMP ERROR_EXIT ;If error, exit.
-
- MESSAGE: CALL CLS ;Clear screen.
- CALL CURSOR_OFF ;Cursor off.
- MOV SI,OFFSET LOADING ;Display sorting message.
- MOV DX,0C19H
- CMP SORT_FLAG,1 ;Unless not sorted.
- JNZ DISP_MSG
- MOV SI,OFFSET LOAD_ONLY ;Then display loading message.
- MOV DX,0C1FH
- DISP_MSG: CALL DISPLAY_TEXT
- MOV FILE_CNT,0000H ;FILE COUNT = ZERO
- MOV COUNT,0000H ;FILE COUNT = ZERO
- MOV DI,OFFSET BUFFER ;Put space character
- MOV CX,16000 ; in directory listing
- MOV AX,2020H ; buffer.
- REP STOSW
-
- MOV DX,OFFSET STAR_DOT_STAR
- MOV CX,SEARCH_ATTRIB
- CALL FIND_FIRST ;Find first matching file.
- JNC STORE_NAME ;If empty directory, exit.
- MOV DI,158 ;Point to filename.
- MOV SI,OFFSET NO_FILES ;Point to MSG
- MOV CX,12 ;Store 12 bytes of filename.
- REP MOVSB
-
- STORE_NAME: MOV DI,OFFSET BUFFER + 1 ;Point to buffer.
- MOV BP,SP ;Reserve space for stack.
- SUB BP,500
- CALL BUFFER_NAME ;Convert to directory format.
-
- FIND_NEXT: MOV AH,4FH ;Find next matching.
- INT 21H
- JC STORE_COUNT ;If carry, no more names.
- CALL BUFFER_NAME
- CMP DI,BP ;Are we encroaching the stack?
- JBE FIND_NEXT ;If no, find next.
- MOV DX,OFFSET TOO_MANY ;Else, exit with message.
-
- ;-----------------------------------------------------------------------;
- ; This is the exit routine. Restore the defaults the way we found them. ;
- ;-----------------------------------------------------------------------;
-
- ERROR_EXIT: MOV AH,9 ;Display error message.
- INT 21H
- ERROR_DISK: MOV TEMPUS_RETCODE,4 ;SET RETURN CODE
- MOV AL,1 ;Error code of one.
- JMP SHORT TERMINATE
-
- ESC_EXIT:
- CMP DEFAULT_MENU,2 ;DEFAULT AT SHORT MENU
- JE EXIT_PGM ;YES
- CMP M4,0 ;SWITCH /M4 ENTERED
- JA EXIT_PGM ;YES
- MOV DEFAULT_MENU,2 ;DEFAULT TO SHORT MENU
- CALL REFRESH_MENU ;AND DISPLAY IT
- RET
- EXIT_PGM: MOV TEMPUS_RETCODE,3 ;SET RETURN CODE
- EXIT: CALL CLS ;Clear screen.
- XOR DX,DX ;Set cursor top left.
- CALL SET_CURSOR
- CALL CURSOR_ON ;Turn cursor back on.
- XOR AL,AL ;Error code of zero.
- TERMINATE: PUSH AX
- MOV AL,CUR_VERIFY ;Restore verify state.
- CALL SET_VERIFY
- MOV DL,CURRENT_DISK ;Restore drive.
- CALL CHANGE_DRIVE
- CALL CURSOR_ON ;Turn cursor back on.
- POP AX
- MOV AL,TEMPUS_RETCODE ;SET RETURN CODE
- MOV AH,4CH
- INT 21H
-
- ;-----------------------------------;
- ; Store buffer end address and page ;
- ; end then sort the filenames. ;
- ;-----------------------------------;
-
- STORE_COUNT: DEC DI
- MOV END_OFFSET,DI ;Store ending offset.
- MOV BX,COUNT ;Retrieve file count.
- CMP BX,21 ;Enough to fill one page?
- JAE DO_SORT ;If yes, use default setting.
- MOV AX,160 ;Calculate last record.
- MUL BL
- ADD AX,BAR_START ;Add bar offset.
- MOV PAGE_END,AX
- DO_SORT: CMP SORT_FLAG,1 ;Should we sort or leave original?
- JZ READY ;If it was "/O", don't sort.
- CALL SORT
-
- ;------------------------------------------------------------------------;
- ; Now, we are ready to get target directory and display it and the menu. ;
- ;------------------------------------------------------------------------;
-
- READY: MOV DI,OFFSET PURGE_DIR B ;Point to storage.
- CALL GET_DRIVE ;Get drive.
- MOV PURGE_DISK,AL
- ADD AL,"A" ;Convert to ASCII.
- STOSB
- MOV AL,":" ;Add colon.
- STOSB
- MOV SI,DI ;Get directory.
- CALL GET_DIR
- MOV SI,OFFSET PURGE_DIR B ;Make a carbon copy of
- MOV DI,OFFSET SOURCE B ; directory.
- CARBON_COPY: MOVSB
- CMP BYTE PTR [SI],0
- JNZ CARBON_COPY
- MOV AL,"\" ;Add "\" to end of path
- CMP [DI-1],AL ; if not root directory.
- JZ STORE_END
- STOSB
- STORE_END: MOV FILE_NAME,DI ;Store end of path to tack
- CALL UPDATE_FREE ; on filename later on.
- MOV DX,OFFSET WORKING_DIR ;Restore the working directory.
- CALL CHANGE_DIR
- MOV DL,CURRENT_DISK ;Restore to default drive
- CALL CHANGE_DRIVE
- MOV DX,OFFSET CURRENT_DIR ; and default directory.
- CALL CHANGE_DIR
- CALL REFRESH_DIR ;Display drive, directory, menu.
- RET
-
- ;-----------------------------------------------------------------------;
- ; This subroutine searches for a filename with a specific first letter. ;
- ;-----------------------------------------------------------------------;
-
- SEARCH: CMP BL,"a" ;Capitalize if lower case.
- JB SEARCH_IT
- CMP BL,"z"
- JA SEARCH_IT
- AND BL,5FH
- SEARCH_IT: CALL GET_NAME ;Get current position.
- XOR DX,DX ;Zero out file counter.
- MOV DI,SI ;Store current position in DI.
- MOV SI,OFFSET BUFFER + 1 ;Point to top of listing.
- CMP BYTE PTR [DI],BL ;Are we currently at a match?
- JNZ NEXT_SEARCH ;If no, start from top.
- FIND_START: INC DX ;Increment count.
- ADD SI,FIELD_SIZE ;Increment record.
- CMP SI,DI ;New record?
- JBE FIND_START ;If no, find it.
-
- NEXT_SEARCH: CMP BYTE PTR [SI],BL ;Got a match?
- JZ FOUND_IT ;If yes, process.
- INC_SEARCH: ADD SI,FIELD_SIZE ;Else, point to next record.
- INC DX
- CMP BYTE PTR [SI],32 ;End of listing?
- JNZ NEXT_SEARCH ;If no, keep searching.
- CALL BEEP ;No matches, so beep.
- RET
-
- FOUND_IT: MOV CX,COUNT ;Retrieve file count.
- SUB CX,DX ;Subtract search count.
- MOV SEARCH_COUNT,CX ;And store.
- MOV CL,ATTR_TREE ;Turn off bar for now.
- MOV BAR_ATTRIBUTE,CL
- CALL END_BAR ;First move to end.
- JMP SHORT FIND_IT
- NEXT_FIND: CALL UP_ARROW2 ;Move up to matching filename.
- FIND_IT: DEC SEARCH_COUNT
- JNZ NEXT_FIND
- MOV CL,INVERSE ;Turn bar back on and display.
- MOV BAR_ATTRIBUTE,CL
- XOR BP,BP
- CALL SCROLL_BAR
- RET
-
- ;--------------------------------------------------------------------------;
- ; This subroutine gets the highlighted file and converts it to DOS format. ;
- ;--------------------------------------------------------------------------;
-
- GET_NAME: MOV SI,CUR_OFFSET ;Get top of page.
- INC SI ;Bump past mark field.
- MOV AX,LINE ;Get location of bar.
- SUB AX,BAR_START ;Adjust.
- MOV CL,160 ;Convert to byte pointer.
- DIV CL
- MOV CL,FIELD_SIZE
- MUL CL
- ADD SI,AX ;Add to current offset.
- MOV CUR_FILE,SI ;And save pointer.
- PUSH SI
- MOV DI,FILE_NAME ;Store the first eight characters.
- MOV CX,8
- CALL STORE_BYTES
- INC SI
- CMP BYTE PTR DS:[SI],32 ;End of name?
- JZ END_NAME ;If yes, done here.
- MOV AL,"." ;Else, add dot.
- STOSB
- MOV CX,3 ;Three possible characters
- CALL STORE_BYTES ; as extension.
- END_NAME: MOV BYTE PTR [DI],0 ;Convert to ASCIIZ.
- POP SI
- CMP BYTE PTR [SI+13],"<" ;Is it a directory?
- STC
- JZ NAME_ERROR ;If yes, indicate so.
- CLC
- NAME_ERROR: RET
-
- STORE_BYTES: LODSB ;Get a character.
- CMP AL,32 ;If it's space, skip.
- JZ SKIP_STORE
- STOSB
- SKIP_STORE: LOOP STORE_BYTES
- RET
-
- ;-----------------------------------------------------------;
- ; This subroutine moves and turns the cursor on and removes ;
- ; the last user entry in preparation for new input. ;
- ;-----------------------------------------------------------;
-
- CLEAR_OLD: CALL SET_CURSOR ;Move cursor.
- CALL CURSOR_ON ;Turn it on.
- MOV DI,OFFSET ENTRY B ;Write nulls over old entry.
- XOR AX,AX
- MOV CX,18
- REP STOSW
- MOV DI,OFFSET ENTRY B ;Initiate pointer for entry.
- RET
-
- ;-----------------------------;
- ; This subroutine backspaces. ;
- ;-----------------------------;
-
- MOVE_BS: CMP DI,OFFSET ENTRY B ;At beginning of field?
- JZ MOVE_BS_END ;If yes, skip.
- DEC DI ;Else, decrement pointer.
- MOV BYTE PTR [DI],0
- MOV SI,OFFSET BS ;Erase last character.
- CALL GET_TEXT
- MOVE_BS_END: RET
-
- ;------------------------------------------------------------------;
- ; This subroutine removes the filename from the directory listing. ;
- ;------------------------------------------------------------------;
-
- REMOVE_FILE: MOV DI,CUR_FILE ;Point to filename.
- DEC DI ;Include mark field.
- MOV SI,DI ;Move all the records
- ADD SI,FIELD_SIZE ; that follow up one.
- NEXT_RECORD: MOV CX,FIELD_SIZE / 2
- REP MOVSW
- CMP DI,END_OFFSET
- JB NEXT_RECORD
- SUB DI,FIELD_SIZE
- MOV END_OFFSET,DI ;Store new end.
- XOR BP,BP
- CALL SCROLL ;Update the screen.
- DEC COUNT
- DEC FILE_CNT ;Decrement file count.
- JNZ MORE_FILES ;If empty, exit.
- JMP EXIT
- MORE_FILES: CMP COUNT,21 ;Full page?
- JAE REMOVE_END ;If yes, skip.
- SUB PAGE_END,160 ;Else, adjust page end.
- MOV SI,PAGE_END
- SUB SI,160
- CMP SI,LINE ;Is bar below directory listing?
- JA REMOVE_END ;If no, skip.
- CALL MOVE_BAR ;Else, move bar up one line.
- REMOVE_END: RET
-
- ;----------------------------------------------;
- ; This subroutine displays the count of files. ;
- ;----------------------------------------------;
-
- FILE_COUNT: MOV DI,OFFSET FILES ;Blank out previous count.
- MOV AX,2020H
- STOSW
- MOV AX,FILE_CNT
- XOR DX,DX
- CALL TRANSLATE
-
- DISPLAY_BYTES: MOV DX,1806H ;Row 24; column 6.
- MOV SI,OFFSET FILES ;Display file count.
- CALL DISPLAY_TEXT
- RET
-
- ;---------------------------------------------------;
- ; This subroutine converts a hex number to decimal. ;
- ;---------------------------------------------------;
-
- TRANSLATE: XCHG AX,DX
- MOV BX,10 ;Convert to decimal.
- STD ;Reverse direction.
- NEXT_COUNT: MOV CX,DX
- XOR DX,DX
- DIV BX
- XCHG AX,CX
- DIV BX
- XCHG AX,DX
- ADD AL,"0" ;Convert to ASCII.
- STOSB ;Store the remainder.
- MOV AX,CX
- OR CX,DX
- JNZ NEXT_COUNT
- CLD ;Back to forward direction.
- RET
-
- ;----------------------------------------------------------------------------;
- ; This subroutine displays the current directory, menu, and number of files. ;
- ;----------------------------------------------------------------------------;
-
- REFRESH_DIR: CALL CLS ;Clear the screen.
- REFRESH_MENU:
- MOV SI,OFFSET MENU ;Point to menu position.
- CMP DEFAULT_MENU,1
- JE LONG_MENU
- MOV SI,OFFSET MENU2 ;Point to menu2 position.
- LONG_MENU:
- MOV DI,(1*160)+98 ;And to screen position.
- MOV BH,MENU_LGTH ;Display 20 lines of menu.
- NEXT_REFRESH: MOV CX,MENU_WIDTH ;22 characters per line.
- NEXT_MENU: LODSB
- MOV BL,AL
- CALL WRITE_SCREEN
- ;----------------------FW--------------------------------------
- MOV BL,ATTR_MENU ;<<<<<<
- DEC DI
- CALL WRITE_SCREEN
- DEC DI
- ;----------------------FW--------------------------------------
- LOOP NEXT_MENU
- ADD DI,160-(MENU_WIDTH*2) ;Next line.
- DEC BH
- JNZ NEXT_REFRESH
-
- MOV DX,2
- MOV SI,OFFSET DIRECTORY ;Display "Directory ".
- CALL DISPLAY_TEXT
- MOV SI,OFFSET PURGE_DIR B ;Display working directory.
- CALL GET_TEXT
- CMP OUTPUT_DIR,00 ;WAS THERE AN OUTPUT ENTERE
- JE SKIP_OUTPUT ;IF NOT SKIP
- MOV SI,OFFSET COPY_MOVE ;Display "Copy or Move to"
- CALL GET_TEXT
- MOV SI,OFFSET OUTPUT_DIR ;Display output drive & dir
- CALL GET_TEXT
- SKIP_OUTPUT: CALL FILE_COUNT ;Display file count.
- ;--------------FW-----------------------------------------------
- MOV AX,LINE
- PUSH AX
- MOV LINE,0
- CALL UPDATE_SCREEN
- POP AX
- MOV LINE,AX
- ;---------------------------------------------------------------
- MOV BL,INVERSE ;Put up cursor bar.
- CALL BAR
- RET
-
- ;-------------------------------------;
- ; This subroutine scrolls the screen. ;
- ;-------------------------------------;
-
- SCROLL: MOV SI,CUR_OFFSET ;Get current offset.
- ADD SI,BP ;Add requested direction.
- CK_LOWER: CMP SI,OFFSET BUFFER ;If above start check upper limit.
- JAE UPPER_LIMIT
- LOWER_LIMIT: MOV CUR_OFFSET,OFFSET BUFFER ;Else, make it start.
- JMP SHORT SCROLL_RETURN ;And update screen.
-
- UPPER_LIMIT: MOV BX,END_OFFSET ;See if beyond end of
- CMP BX,OFFSET BUFFER + 21 * FIELD_SIZE ; directory listing.
- JA CK_UPPER
- MOV CUR_OFFSET,OFFSET BUFFER
- JMP SHORT SCROLL_RETURN
-
- CK_UPPER: SUB BX,21 * FIELD_SIZE
- CMP SI,BX
- JBE END_SCROLL
- MOV SI,BX
-
- END_SCROLL: MOV CUR_OFFSET,SI ;Update current offset.
- SCROLL_RETURN:
- RET
-
- ;--------------------------------------------------;
- ; This subroutine scrolls the bar if between start ;
- ; and end of page. Otherwise the page is scrolled. ;
- ;--------------------------------------------------;
-
- SCROLL_BAR: MOV SI,LINE ;Get current line.
- ADD SI,BP ;Add requested line.
- MOV BP,- FIELD_SIZE ;Assume below beginning.
- CMP SI,BAR_START ;Is it?
- JB SCROLL_PAGE ;If yes, scroll page instead.
- MOV BP,FIELD_SIZE ;Do the same for end of page.
- CMP SI,PAGE_END
- JAE SCROLL_PAGE
- CALL MOVE_BAR
- RET
-
- SCROLL_PAGE: CALL SCROLL
- RET
-
- ;----------------------------------------------------;
- ; This subroutine does the actual moving of the bar. ;
- ;----------------------------------------------------;
-
- MOVE_BAR:
- MOV BL,ATTR_TREE ;Remove old bar.
- CALL BAR
- MOV LINE,SI ;And move bar to new line.
- MOV BL,BAR_ATTRIBUTE
- CALL BAR
- RET
-
- BAR: MOV DI,LINE ;Retrieve line.
- MOV CX,BAR_LENGTH ;Bar length 39.
- NEXT_BAR: CALL WRITE_SCREEN ;Write the attribute.
- LOOP NEXT_BAR
- RET
-
- ;-------------------------------------------------;
- ; This subroutine displays the directory listing. ;
- ;-------------------------------------------------;
-
- UPDATE_SCREEN: XOR BP,BP
- MOV SI,CUR_OFFSET ;Retrieve starting offset.
- MOV DI,2*160 ;Point to row two of screen.
- MOV BH,21 ;21 lines to write.
- NEXT_WRITE: MOV CX,FIELD_SIZE ;44 characters per line.
- MOV BL,ATTR_TREE ;ELSE USE TREE ATTR
- MOV ATTR_SAVE,BL ;ELSE USE TREE ATTR
- NEXT_CHAR:
- ;----------------------FW--------------------------------------
- MOV AX,LINE
- ADD AX,-1
- CMP AX,DI ;FIND HIGHLIGH
- JNE MOVE_ATTR
- MOV BL,BAR_ATTRIBUTE
- MOV ATTR_SAVE,BL ;ELSE USE BAR ATTR
- MOVE_ATTR:
- ;--------------------------------------------------------------
- LODSB ;Get a byte.
- MOV BL,AL ;Save it in BL.
- CALL WRITE_SCREEN ;Write them.
- ;----------------------FW--------------------------------------
- MOV BL,ATTR_SAVE ;ELSE USE TREE ATTR
- DEC DI
- CALL WRITE_SCREEN
- DEC DI
- ;--------------------------------------------------------------
- LOOP NEXT_CHAR
- NOATTR: ADD DI,160 - FIELD_SIZE * 2 ;Bump pointer to next line.
- DEC BH ;Do all 21 lines.
- JNZ NEXT_WRITE
- RET
-
- ;------------------------------------------------------------;
- ; This subroutine displays the directory by writing directly ;
- ; to the screen buffer. To avoid screen noise (snow) on the ;
- ; color card, the horizontal retrace has to be monitored. ;
- ;------------------------------------------------------------;
-
- WRITE_SCREEN: MOV DX,STATUS_REG ;Retrieve status register.
- MOV AX,VIDEO_SEG ;Point to screen segment.
- MOV ES,AX
-
- HORZ_RET: IN AL,DX ;Get status.
- TEST AL,1 ;Is it low?
- JNZ HORZ_RET ;If not, wait until it is.
- CLI ;No more interrupts.
-
- HWAIT: IN AL,DX ;Get status.
- TEST AL,1 ;Is it high?
- JZ HWAIT ;If no, wait until it is.
- MOV AL,BL ;Retrieve character; now it's OK
- STOSB ; to write to screen buffer.
- STI ;Interrupts back on.
- INC DI ;Bump pointer past attribute.
- PUSH CS
- POP ES
- RET ;Return
-
- ;-----------------------------------------------------------------------;
- ; These two subroutines clear either the messages or the entire screen. ;
- ;-----------------------------------------------------------------------;
-
- CLS_TEXT: XOR CX,CX
- MOV DX,184FH ;Entire screen.
- JMP CLEAR_WINDOW
-
- CLS: XOR CX,CX
- MOV DX,184FH ;Entire screen.
- CALL CLEAR_WINDOW
-
- CLEAR_MSG: MOV CX,152CH ;Row 24; column 43.
- MOV DX,184FH ;Row 25; column 79.
- PUSH BP
- PUSH BX
- MOV BH,ATTR_MSGS ;Clear with original attribute.
- JMP SHORT CLEAR_WINDOW2
-
- CLEAR_WINDOW: PUSH BP
- PUSH BX
- MOV BH,ATTR_TEXT ;Clear with original attribute.
- CLEAR_WINDOW2: MOV AX,600H
- INT 10H
- POP BX
- POP BP
- RET
-
- ;-----------------------------------------;
- ; These subroutines display the messages. ;
- ;-----------------------------------------;
-
- DISPLAY_TEXT: CALL SET_CURSOR ;Move cursor.
- GET_TEXT: LODSB
- CMP AL,0 ;Zero marks end of string.
- JZ END_TEXT
- ;--------------------FW----------------------------------------
- MOV BL,ATTR_MSGS
- ;--------------------------------------------------------------
- CALL WRITE_TEXT
- JMP SHORT GET_TEXT
- END_TEXT: RET
-
- WRITE_TEXT: PUSH SI ;BIOS does not save SI.
- MOV AH,0EH ;Write teletype.
- INT 10H
- POP SI
- RET
-
- ;--------------------------------------------------------------;
- ; These two subroutines change the default drive or directory. ;
- ;--------------------------------------------------------------; *
-
- GET_DRIVE: MOV AH,19H
- INT 21H
- RET
-
- CHANGE_DRIVE: MOV AH,0EH
- INT 21H
- RET
-
- ;---------------------------------------------;
- ; These two subroutines open or close a file. ;
- ;---------------------------------------------;
-
- OPEN_FILE: MOV AH,3DH
- INT 21H
- RET
-
- CLOSE_FILE: MOV AH,3EH
- INT 21H
- RET
-
- ;------------------------------------------------;
- ; This subroutine finds the first matching file. ;
- ;------------------------------------------------;
-
- FIND_FIRST: MOV AH,4EH
- INT 21H
- RET
-
- ;--------------------------------------------------------------;
- ; These two subroutines retrieve or change a file's attribute. ;
- ;--------------------------------------------------------------;
-
- CHMOD: MOV AX,4301H
- INT 21H
- RET
-
- GETMOD: MOV AX,4300H
- INT 21H
- RET
-
- ;---------------------------------------------------------;
- ; This subroutine gets the free disk space of the target. ;
- ;---------------------------------------------------------;
-
- GET_DISK: MOV SI,DX ;Retrieve pointer to target file.
- MOV DL,-1 ;Assume default drive.
- CMP BYTE PTR [SI+1],":" ;Is there a drive request?
- JNZ GET_FREE ;If no, get default drive.
- MOV DL,[SI] ;Else, retrieve drive request.
- AND DL,5FH ;Capitalize.
- SUB DL,"A" ;Convert to DOS format.
- GET_FREE: CALL DISK_FREE ;Get free bytes.
- RET
-
- ;--------------------------------------------------------------;
- ; This subroutine gets the free disk space of the source drive ;
- ;--------------------------------------------------------------;
-
- UPDATE_FREE: MOV DL,PURGE_DIR B ;Get source drive.
- SUB DL,"A" ;Convert to DOS format.
- CALL DISK_FREE ;Get disk free space.
- MOV DI,OFFSET FILES + 20 ;Point to storage.
- CALL TRANSLATE ;Convert hex to decimal and store.
- RET
-
- ;----------------------------------------------;
- ; This subroutine retrieves available clusters ;
- ; and converts it to hexidecimal bytes free. ;
- ;----------------------------------------------;
-
- DISK_FREE: INC DL ;Adjust drive.
- MOV AH,36H ;Disk free space.
- INT 21H
- XOR DX,DX
- MUL BX ;Sectors per cluster times clusters
- MUL CX ;Result times bytes per cluster.
- RET
-
- ;------------------------------------------;
- ; This subroutine converts hex to decimal. ;
- ;------------------------------------------;
-
- GET_COUNT: MOV BX,10 ;Convert to decimal.
- XOR CX,CX ;Zero in counter.
- GET_NUMBER: XOR DX,DX ;Zero in high half.
- DIV BX
- ADD DL,"0" ;Convert to ASCII.
- PUSH DX ;Save results.
- INC CX ;Also increment count.
- CMP AX,0 ;Are we done?
- JNZ GET_NUMBER
-
- NEXT_NUMBER: POP AX ;Retrieve numbers.
- CALL WRITE_TEXT ;And write them.
- LOOP NEXT_NUMBER
- RET
-
- ;---------------------------------------------------------;
- ; These five subroutines move the cursor, get the current ;
- ; directory, beep the speaker, check or get a keystroke. ;
- ;---------------------------------------------------------;
-
- SET_CURSOR: PUSH SI
- XOR BH,BH ;Page zero.
- MOV AH,2 ;Set cursor.
- INT 10H
- POP SI
- RET
-
- GET_DIR: MOV BYTE PTR [SI],"\" ;DOS doesn't preface directory
- INC SI ; with slash so we must.
- XOR DL,DL
- MOV AH,47H ;Retrieve default directory.
- INT 21H
- RET
-
- BEEP: MOV DL,7 ;Beep via DOS.
- MOV AH,2
- INT 21H
- RET
-
- READ_KEY: MOV AH,0 ;Retrieve keystroke via BIOS.
- INT 16H
- RET
-
- CK_KEY: MOV AH,1 ;Check for keystroke via BIOS.
- INT 16H
- RET
-
- ;-------------------------------------------------------------;
- ; This subroutine waits until a keystroke is pressed and then ;
- ; clears the message. Keystroke remains in keyboard buffer. ;
- ;-------------------------------------------------------------;
-
- DELAY: CALL CK_KEY
- JZ DELAY
- CALL CLEAR_MSG
- RET
-
- ;-----------------------------------------------;
- ; These subroutines turn the cursor off and on. ;
- ;-----------------------------------------------;
-
- CURSOR_OFF: MOV CX,2000H
- JMP SHORT SET_TYPE
-
- CURSOR_ON: MOV CX,CURSOR_TYPE
-
- SET_TYPE: MOV AH,1
- INT 10H
- RET
-
- ;------------------------------------------------;
- ; This subroutine changes the default directory. ;
- ;------------------------------------------------;
-
- CHANGE_DIR: MOV AH,3BH
- INT 21H
- RET
-
- ;------------------------------------------------;
- ; This subroutine changes the copy verify state. ;
- ;------------------------------------------------;
-
- SET_VERIFY: MOV AH,2EH
- INT 21H
- RET
-
- ;------------------------------------------;
- ; This subroutine MOVES TEST FROM SI TO DI ;
- ;------------------------------------------;
-
- MOVE_TEXT: LODSB
- CMP AL,0 ;Zero marks end of string.
- JZ MOVE_TEXT_END
- STOSB
- JMP MOVE_TEXT
- MOVE_TEXT_END: RET
-
- ;--------------------------------------------------;
- ; This long subroutine stores the filename in DIR ;
- ; format. That is, filename, bytes, date and time. ;
- ;--------------------------------------------------;
-
- BUFFER_NAME: MOV SI,158 ;Point to filename.
- MOV CX,12 ;Store 12 bytes of filename.
- CMP BYTE PTR [SI],"." ;Is it a dot directory?
- JNZ INC_COUNT ;If no, it's a file.
- JMP DONT_STORE ;If no, single dot so skip.
- CMP BYTE PTR [SI+1],"." ;Is it a double dot directory?
- JNZ DONT_STORE ;If no, single dot so skip.
- INC COUNT ;Else, increment total count.
- LODSB ;Store dots and go to file size.
- STOSB
- STOSB
- ADD DI,10
- JMP SHORT FILE_SIZE
- DONT_STORE: RET
-
- INC_COUNT: INC COUNT ;Increment total count.
- NEXT_STORE: LODSB ;Get a byte.
- CMP AL,0 ;End of filename?
- JZ END_STORE ;If yes, finish with blanks.
- CMP AL,"." ;Is it the period?
- JNZ STORE_BYTE ;If no, store.
- SUB CX,3 ;Else store 3 spaces.
- MOV AL,32
- REP STOSB
- ADD CX,3
- JMP SHORT NEXT_STORE ;Get next byte.
-
- STORE_BYTE: STOSB ;Store byte.
- LOOP NEXT_STORE ;Get next byte.
- END_STORE: MOV AL,32 ;Pad balance with spaces.
- REP STOSB
-
- FILE_SIZE: PUSH DI ;Save pointer.
- TEST BYTE PTR DS:[149],10H ;Is it a directory?
- JZ STORE_SIZE ;If no, store size.
- MOV SI,OFFSET DIRECTORIES ;Else, store "<DIR>".
- INC DI
- MOV CX,5
- REP MOVSB
- JMP SHORT END_DATE
-
- STORE_SIZE: INC FILE_CNT ;Increment file count.
- ADD DI,8 ;Move to end of bytes field.
- MOV DX,DS:[156] ;Retrieve high and low words
- MOV AX,DS:[154] ; of bytes.
- CALL TRANSLATE ;Convert to decimal.
-
- END_DATE: POP DI ;Retrieve pointer.
- ADD DI,11 ;Move to date field.
- DATE: MOV DX,DS:[152] ;Retrieve date.
- MOV AX,DX
- MOV CL,5 ;Shift to lowest bits.
- ROR AX,CL
- AND AX,0FH ;Mask off all but month.
- MOV CL,0FFH ;Flag as no leading zeros.
- MOV CH,"-" ;Delimiting character.
- CALL STORE_WORD ;Store it.
-
- MOV AX,DX ;Retrieve date.
- AND AX,1FH ;Mask off all but day.
- MOV CL,0 ;Flag include leading zeros.
- MOV CH,"-"
- CALL STORE_WORD ;Store it.
-
- MOV AX,DX ;Retrieve date for last time.
- MOV CL,9
- ROR AX,CL
- AND AX,7FH ;Mask off all but year.
- ADD AX,80 ;Adjust to ASCII.
- CMP AX,100 ;Past year 2000?
- JB DISPLAY_DATE ;If no, display. Else, adjust for
- SUB AX,100 ; next century. (Planning ahead!)
- DISPLAY_DATE: MOV CL,0 ;Display leading zeros.
- MOV CH,32
- CALL STORE_WORD ;Store it.
-
- TIME: INC DI ;Move to time field.
- MOV DX,DS:[150] ;Retrieve time.
- MOV AX,DX
- MOV CL,11 ;Shift to hours bits.
- ROR AX,CL
- AND AX,1FH ;Mask off all but hours.
- PUSH AX
- CMP AX,12 ;Past noon?
- JBE MERIDIAN
- SUB AX,12 ;If yes, adjust.
- MERIDIAN: CMP AX,0 ;Midnight?
- JNZ NOT_MIDNIGHT
- MOV AX,12 ;If yes, adjust.
- NOT_MIDNIGHT: MOV CL,0FFH ;Suppress leading zeros.
- MOV CH,":"
- CALL STORE_WORD ;Store it.
-
- MOV AX,DX ;Retrieve time.
- MOV CL,5 ;Shift to minutes bits.
- ROR AX,CL
- AND AX,3FH ;Mask off all but minutes.
- MOV CL,0
- POP DX ;Retrieve hours.
- MOV CH,"p" ;Assume PM.
- CMP DX,12 ;Is it PM?
- JAE PM
- MOV CH,"a" ;If no, AM.
-
- PM: CALL STORE_WORD ;Store it.
- MOV AH,BYTE PTR DS:[149] ;Get attribute byte.
- MOV AL,"H" ;Assume it's hidden.
- TEST AH,2 ;Is it?
- JNZ HIDDEN ;If yes, store "H".
- MOV AL,32 ;Else, store a space.
- HIDDEN: STOSB
- MOV AL,"S" ;Assume it's system.
- TEST AH,4 ;Is it?
- JNZ SYSTEM ;If yes, store "S".
- MOV AL,32 ;Else, store a space.
- SYSTEM: STOSB
- MOV AL,"R" ;Assume it's read-only.
- TEST AH,1 ;Is it?
- JNZ READ_ONLY ;If yes, store "R".
- MOV AL,32 ;Else, store a space.
- READ_ONLY: STOSB
- MOV AL,"A" ;Assume it's archive.
- TEST AH,20H ;is it?
- JNZ ARCHIVE ;If yes, store "A".
- MOV AL,32 ;Else store a space.
- ARCHIVE: STOSB
- INC DI ;Bump pointer past mark field.
- RET
-
- ;-------------------------------;
-
- STORE_WORD: MOV BL,10
- DIV BL ;Divide by ten.
- ADD AX,"00" ;Convert to ASCII.
- CMP CL,0 ;Are we to display leading zero?
- JZ STORE_IT ;If yes, store as is.
- CMP AL,"0" ;Is it a leading zero?
- JNZ STORE_IT ;If no, store it.
- MOV AL,32 ;Else, store a space.
- STORE_IT: STOSW
- MOV AL,CH ;Store delimiter character also.
- STOSB
- RET
-
- ;-------------------------------------------;
- ; This is the new Critical Error interrupt. ;
- ;-------------------------------------------;
-
- DISK_ERROR: STI ;Interrupts back on.
- PUSHF ;Save all registers.
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
- PUSH DS
- PUSH ES
-
- PUSH AX ;Save failed drive number.
- MOV AX,CS
- MOV DS,AX ;Point to our data segment.
- MOV ES,AX
-
- CALL CLEAR_MSG ;Clear current message.
- MOV SI,OFFSET DISK_MSG ;Display disk error message.
- MOV DX,172FH
- CALL DISPLAY_TEXT
- POP AX ;Retrieve fail drive and display.
- ADD AL,"A"
- CALL WRITE_TEXT
- MOV DX,182FH ;Display rest of error message.
- CALL DISPLAY_TEXT
-
- WAIT_KEY: CALL READ_KEY ;Get a response to message.
- CMP AH,K_R ;Was it scan code for "R"?
- JZ END_DISK ;If yes retry.
- CMP AH,K_Q ;Was it "Q"?
- JNZ WAIT_KEY ;If no, wait until correct response
- JMP EXIT ;Else, exit to DOS.
-
- END_DISK: CALL CLEAR_MSG ;Clear disk error message.
- POP ES ;Restore registers.
- POP DS
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- POPF
- MOV AL,1 ;Return with retry request.
- IRET
- ;
- PAGE 60,132
-
- ;Usage is: call envsub ds:si -> length,string
-
- ; length is 1 byte long, <128
- ; if high bit on, primary environment is set.
- ; string is of form: name=value
-
- ; Copyright 1987, A. B. Krueger GPW MI 48236
- ; All rights reserved. Contact "ARNY KRUEGER"
- ; at the EXEC-PC BBS (414-964-5160) for permission
- ; to use commercially.
- ;
-
- ;Clone of SET command that demonstrates updating
- ; the environment string.
- ;If there is no secondary command processor, the
- ; global environment is updated
- ;If there is a secondary command processor, then
- ; its enviroment is updated
-
- sb segment at 0 ;equates storage blocks and psp's
-
- sb_kind db ' ' ;type of storage block: 'M' or 'Z'
- sb_psp dw ? ;psp segment address
- sb_length dw ? ;sb length in paragraphs
- sb_head_length equ 10h ;length of sb header
- org sb_head_length
- sb_data db ? ;data in block
-
- org 0h ;program segement prefix equates
- psp_ret_int dw ? ;int 20h
- org 2Ch
- psp_env dw ? ;segment address of environment
- org 50h
- psp_dos_function dw ? ;address of function dispatcher
- org 80h
- psp_parm_string db ? ;1 byte length plus parm string
-
- psp_length equ 100h
-
- sb ends
-
- code_seg segment para public
- assume cs:code_seg,ds:code_seg,es:sb
- public env_set
-
- ;local data
-
- cr equ 13
- lf equ 10
-
- sb_count dw 0 ;count of sb's encountered
- sb_shell dw 0 ;segment address of shell sb
- sb_shell_env dw 0 ;segment address of global env sb
- sb_secondary dw 0 ;segment address of secondary command.com
- sb_secondary_env dw 0 ;segment address of secondary command env
-
- fatal_msg equ 80h
- error_msg equ 40h
- info_msg equ 20h
- msg_flag db fatal_msg+error_msg ;+info_msg ;set flags
- db 'Copyright 1987, A. B. Krueger GPW MI 48236'
- secondary_msg db info_msg,'Secondary '
- command_found db info_msg,'COMMAND.COM found',cr,lf,'$'
- bad_dos_msg db fatal_msg,'Must be running under DOS 2.0 or above',cr,lf,'$'
- bad_sb_msg db fatal_msg,'Bad storage block',cr,lf,'$'
- bad_env_msg db error_msg,'Bad environment block',cr,lf,'$'
- command_lost db error_msg,'Shell never found',cr,lf,'$'
- addbadmsg db error_msg,'Environment corrupt',cr,lf,'$'
- addmsg db info_msg,'Addition requested',cr,lf,'$'
- removemsg db info_msg,'Removal requested',cr,lf,'$'
- env_set_nospace db error_msg,'No space in environment string',cr,lf,'$'
- env_set_syntax db error_msg,'Set string syntax error',cr,lf,'$'
-
- type_string proc near ;type message at offset in dx
- push ax ;save registers
- push cx
- push dx
- push si
-
- mov si,dx ;get message level
- lodsb
- and al,msg_flag ;compare to what sells
- jz type_ret ;if not on list, send to bit bucket
-
- mov dx,si
- mov ax,0900h
- int 21h
- type_ret:
- pop si
- pop dx
- pop cx
- pop ax
- ret
- type_string endp
-
- get_first_sb proc near ;get first storage block, point es at it
- push ax
- push bx
- mov ax,5200h
- int 21h ;es:bx points to memory block anchor+2
- dec bx
- dec bx
- mov es,es:[bx] ;get first memory block address into es
- pop bx
- pop ax
- ret
- get_first_sb endp
-
- get_next_sb proc near
- push ax
- mov ax,es ;get current paragraph
- add ax,es:sb_length ;add in number of paragraphs
- inc ax ;add 1 for header
- mov es,ax ;set new extra segment address
- pop ax
- ret
- get_next_sb endp
-
-
- find_secondary_env proc near ;find env sb's for current program sb
- push ax ;pointed to by es
- push es
- mov ax,es ;get address of secondary cp's sb
- inc ax ;get its psp address
- find_secondary_env_loop:
- call get_next_sb ;get next sb
- cmp ax,es:sb_psp ;match secondary's psp?
- jne find_secondary_env_next ;if not, skip
-
- mov sb_secondary_env,es ;otherwise, save
- jmp find_secondary_env_exit ;and check no further
- ;lest we trash a .BAT block
- find_secondary_env_next:
- cmp es:sb_kind,'Z' ;last block?
- jne find_secondary_env_loop
-
- find_secondary_env_exit:
- pop es
- pop ax
- ret
- find_secondary_env endp
-
- command_test proc near ;test program storage block at es:0
- push ax
- push bx
- push cx
- push dx
- push ds
- push es
- push si
-
- cmp sb_count,2
- ja command_second
-
- mov dx,offset command_found
- call type_string
- mov sb_shell,es
- jmp command_test_good
-
- command_second:
- cmp sb_shell,0 ;did we find shell?
- je command_first_bad ;if not, error
-
- cmp word ptr es:psp_env+es:sb_head_length,0 ;check envir of program
- je command_test_good ;if no environment, quit
-
- push sb_shell
- pop ds ;ds points to shell
- mov al,byte ptr es:sb_head_length+es:psp_length
- cmp al,0E9h ;a JMP?
- jne command_test_good ;if not, no harm done
-
- cmp al,byte ptr ds:sb_head_length+es:psp_length ;check 1st instruction
- jne command_first_bad
-
- mov si,es:sb_head_length+es:psp_length
- mov di,es:sb_head_length+es:psp_length
- mov cx,10 ;look at 10 words of code
- repz cmpsw
- clc
- jcxz command_test_found ;if they all match, fine
-
- jmp command_test_good ;if not, no harm done
-
- command_test_found:
- push cs
- pop ds
- mov sb_secondary,es
-
- mov ax,es:psp_env+es:sb_head_length ;get env address
- dec ax ;back up over sb header
- mov sb_secondary_env,ax ;and save it
-
- call find_secondary_env ;look for other env's
-
- mov dx,offset secondary_msg
- call type_string
- jmp command_test_good
-
- command_first_bad:
- mov dx,offset command_lost
- call type_string
- stc
- jmp command_test_end
-
- command_test_good:
- clc
- command_test_end:
- pop si
- pop es
- pop ds
- pop dx
- pop cx
- pop bx
- pop ax
-
- ret
- command_test endp
-
-
-
- prog_test proc near ;test block for program
- push ax ;save registers
- push cx
- push dx
- push es
-
- mov ax,es:sb_psp ;get PSP of owner
- cmp ax,0 ;if zero, it is free
- je prog_exit
-
- cmp ax,8 ;if PSP of owner is at 8
- je prog_exit ;block owned by config.sys
-
- sub ax,es:sb_head_length ;get address of sb containg program
- cmp ax,sb_shell ;is owner the primary shell?
- je prog_exit
- push es
- pop ax
- cmp ax,es:sb_psp ;compare to address of owner
- ja prog_exit ;if owner below SB, system-owned
-
- add ax,es:sb_length ;add in length
- cmp ax,es:sb_psp ;compare to owner's PSP
- JB prog_exit ;if end below owner PSP, no program
- cmp es:sb_length,10 ;is block long enough to have a psp?
- jbe prog_exit ;if not, no program
-
- mov ax,word ptr es:psp_dos_function+es:sb_head_length
- cmp ax,word ptr cs:psp_dos_function ;check PSP validity
- jne prog_exit
-
- mov ax,word ptr es:psp_ret_int+es:sb_head_length
- cmp ax,word ptr cs:psp_ret_int ;check PSP validity
- jne prog_exit ;if invalid, skip looking for env
-
- call command_test
- clc
- prog_exit:
-
- pop es ;restore registers
- pop dx
- pop cx
- pop ax
- ret
-
- prog_test endp
-
- sb_scan proc near ;loop cx storage blocks
-
- mov al,es:sb_kind ;get storage block type byte
- cmp al,04dh ;ordinary storage block
- je sb_scan_got
- cmp al,05ah
- jne sb_scan_bad
- mov cx,1 ;last block
-
- sb_scan_got:
- inc sb_count ;count storage blocks
-
- cmp sb_count,3 ;blocks 1 and 2 not global env
- jb sb_scan_not_global
-
-
- cmp sb_count,4 ;blocks 5-up not global env
- ja sb_scan_not_global
-
- cmp sb_shell_env,0 ;do we have an env yet ?
- ja sb_scan_not_global ; yes, forget this one
-
- cmp es:sb_data,'!' ;this block an environment ?
- jb sb_scan_not_global ; no, obviously not
-
- cmp es:sb_data,'~' ;this block an environment ?
- ja sb_scan_not_global ; no, obviously not
-
- mov sb_shell_env,es
- jmp sb_scan_get
-
- sb_scan_not_global:
- call prog_test ;look for program
-
- loop sb_scan_get
- jmp sb_scan_end
-
- sb_scan_get:
- call get_next_sb
- jmp sb_scan
-
- sb_scan_end:
- clc
- jmp sb_scan_exit
-
- sb_scan_bad:
- mov al,2
- mov dx,offset bad_sb_msg
- stc
-
- sb_scan_exit:
- ret
- sb_scan endp
-
-
- sb_anal proc near ;proc to analyze storage blocks
- ; to find environment(s)
- push ax
- push cx
- push dx ;carry flag = error
- push es ;error level in al
- mov ah,30h ;get release number
- int 21h
- cmp al,01h ;above dos 1.x?
- jna sb_bad_dos
-
- cld ;clear direction flag
- call get_first_sb
- mov cx,9999 ;scan all blocks
- call sb_scan
- jc sb_send_msg ;if any errors, exit
-
- jmp sb_exit
-
- sb_bad_dos:
- mov al,1
- mov dx,offset bad_dos_msg
- stc
- jmp sb_send_msg
-
- sb_bad_env:
- mov al,3
- mov dx,offset bad_env_msg
- stc
- sb_send_msg:
- pushf
- call type_string
- popf
- sb_exit:
- pop es
- pop dx
- pop cx
- pop ax
-
- ret
- sb_anal endp
-
- make_upper proc near ;make cx bytes at es:di upper case
-
- push ax ;save registers modified
- push cx
- push di
- push ds
- push si
-
- push es
- pop ds
- mov si,di
- make_upper_loop:
- lodsb ;get a byte
- cmp al,'a' ;if lower case:
- jb make_upper_next
- cmp al,'z'
- ja make_upper_next
- and al,255-'a'+'A' ;make upper case
- make_upper_next:
- stosb ;store out results
- loop make_upper_loop
-
- pop si ;restore registers
- pop ds
- pop di
- pop cx
- pop ax
- ret
- make_upper endp
-
-
-
- env_var_name proc near ;find environment variable name at
- push ax ; ds:si, length in cx
- push bx ;at exit, ds:di points to name
- push di ; name length in cx
- push es ;variable contents length to dx
-
- push cx ;save length and pointer
- push si ;for error exits
-
- jcxz env_var_name_bad ;if length is 0, exit
-
-
- push cs ;scan works at es:di
- pop es
- mov di,si
- mov al,' ' ;scan for non-blank
-
- env_var_strip:
- repz scasb ;look for non-blank
- jcxz env_var_name_bad ;if all blank, error!
-
- inc cx ;back up over non-blank character
- dec di
- mov si,di ;save start of non-blank string
- mov bx,cx ;save length
-
- repnz scasb ;look for a blank
- mov dx,di ;save location of ' ' or end
-
- mov cx,bx ;reset search length
- mov di,si ;reset search pointer
- mov al,'=' ;search for equals sign
- repnz scasb
- jne env_var_name_bad ;if not found, error
-
- cmp di,dx ;compare location of '=' and ' '
- ja env_var_name_bad ;found ' ' first? then exit
-
- mov dx,bx ;restore search length
- add dx,si ;add start
- sub dx,di ;subtract where '=' was
-
- pop ax ;pop old si from stack
- pop ax ;pop old cx from stack
-
- mov cx,di ;where we found '='
- sub cx,si ;subtract string start
- dec cx ;minus 1 for '='
- clc ;all is well
- jmp env_var_name_exit
-
- env_var_name_bad:
- pop si ;restore pointer and length
- pop cx
- xor dx,dx ;contents length assumed zero
- stc ;problems - set carry
-
- env_var_name_exit:
- pop es
- pop di
- pop bx ;restore registers
- pop ax
- ret
-
- env_var_name endp
-
- get_sb_size proc near ;get byte size of sb at es:0 in cx
- push ax
- mov ax,es:sb_length ;get length of env in paragraphs
- mov cl,4 ;times 16
- shl ax,cl
- mov cx,ax
- pop ax
- ret
- get_sb_size endp
-
- env_var_find proc near ;find environment variable
- ;named in ds:si,name length in cx
- ;return string start in es:di
- ;length of entire string in cx
- push ax ;save registers
- push bx
- push dx
-
- mov bx,cx ;save length of name
- push es ;save env block address
- push ds ;set es:di to source string
- pop es ; "
- mov di,si ;make name upper case
- call make_upper ;altering input string
- pop es ;restore es to environment block
-
- call get_sb_size ;get size of sb in bytes
-
- mov di,es:sb_head_length ;start at data portion of block
- mov dx,cx ;save block length
-
- env_var_find_loop:
- push si ;save string pointers
- push di
-
- mov cx,bx ;compare for length of name
- mov ah,1 ;say not compare
- repz cmpsb ;compare item to name for name length
- jne env_var_find_next ;if not found, scan on
-
- cmp byte ptr es:[di],'=' ;check next byte for '='
- jne env_var_find_next ;if found, go calc length
-
- mov ah,0 ;say compare ok
- env_var_find_next:
- pop di ;restore string pointers
- pop si
-
- xor al,al ;look for end of current substring
- mov cx,dx ;search remainder of string
- mov dx,di ;save search start
- repnz scasb ;search for a zero
- jne env_var_find_end ;none found, error
-
- cmp ah,0 ;did original compare fly?
- je env_var_find_found;if so, then pass length, etc
-
- cmp byte ptr es:[di],0 ;check next byte for zero
- je env_var_find_end ;if found, name not found
-
- mov dx,cx ;save length of string remaining
- jmp env_var_find_loop ;and loop on
-
- env_var_find_end:
- xor cx,cx ;length = 0, none found
- stc ;set error flag
- jmp env_var_find_exit
-
- env_var_find_found:
- mov cx,di ;save count of end of string
- mov di,dx ;restore search start
- sub cx,di ;calc length of search
- dec cx ;less length of zero
- clc ;no errors
-
- env_var_find_exit:
- pop dx
- pop bx ;restore registers
- pop ax
- ret
- env_var_find endp
-
-
- null_var dw -1
-
- env_var_add proc near ;add environment variable
- ;expression ->ds:si, length in cx
- push ax ;save registers
- push bx
- push dx
-
- mov dx,offset addmsg
- call type_string
- mov bx,cx
- push si
- mov si,offset null_var ;send on wild goose chase
- mov cx,2 ;looking for x'ffff'
- call env_var_find ;es:di points to end of env
- pop si
- jnc env_var_add_env_bad
- ;es:di now points to end of env
- call get_sb_size ;get length of env area in cx
- add cx,es:sb_head_length ;add head length for offsets
- sub cx,bx ;deduct length of string
- sub cx,2 ;deduct length of flag
- cmp di,cx ;compare to where we add
- ja env_var_add_bad ;if no space, too bad
-
- mov cx,bx ;length of string to add
- rep movsb ;do the deed
- xor ax,ax ;make flag of two zeros
- stosw ;add is on
-
- jmp env_var_add_good
-
- env_var_add_env_bad:
- mov dx,offset addbadmsg
- call type_string
-
- env_var_add_bad:
- stc
- jmp env_var_add_exit
-
- env_var_add_good:
- clc
- env_var_add_exit:
- pop dx ;restore registers
- pop bx
- pop ax
- ret
-
- env_var_add endp
-
-
- env_var_remove proc near ;remove environment variable
- ;at es:di, length in cx
- push cx
- push dx
- push ds
- push di
- push si
-
- cld ;move left to right
-
- mov dx,offset removemsg
- call type_string
-
- inc cx ;add 1 for zero byte
- mov dx,cx ;save length of var
- call get_sb_size ;cx gets length of env area
- add cx,es:sb_head_length ;add header length for offsets
- sub cx,di ;deduct where we start
- sub cx,dx ;deduct length of removed variable
-
- mov si,di ;move from next variable
- add si,dx ;add my length
-
- push es ;do all the work in es:
- pop ds
-
- rep movsb ;do the move
-
- pop si
- pop di
- pop ds
- pop dx
- pop cx
- ret
- env_var_remove endp
-
-
- env_set proc near ;change environment per ds:si
- push ax
- push bx ;ds:si points to:
- push cx ; length db ?
- push di
- push ds ; data db 'name=value'
- push es
- push si
- mov sb_count,0 ;count of sb's encountered
- mov sb_shell,0 ;segment address of shell sb
- mov sb_shell_env,0 ;segment address of global env sb
- mov sb_secondary,0 ;segment address of secondary command.com
- mov sb_secondary_env,0 ;segment address of secondary command env
-
- xor ax,ax ;set length of local set string
- lodsb ;get length, push di forward
- mov cx,ax ;length of set string in cx
- and cl,0ffh-80h ;length < 128
- call sb_anal ;analyze the storage block chain
- ;to find command processor(s)
-
- and al,80h ;was use primary switch on?
- jnz env_set_shell ;if so, skip secondaries
-
- cmp sb_secondary_env,0 ;is there a secondary command proc?
- je env_set_shell ;if not, use primary
-
- mov es,sb_secondary_env ;command processor is secondary
- jmp env_set_command
-
- env_set_shell: ;command processor is shell
- mov es,sb_shell_env
- env_set_command:
- call env_var_name ;find what we want set at call
- ;ds:si -> expression, cx has length
- ;at return ds:si -> name
- ;cx is length of name
- jc env_set_syntax_err ;if not found, error
-
- mov bx,cx ;calculate new length of set string
- inc bx ;add 1 for '='
- add bx,dx ;add length of set string
-
- call env_var_find ;find variable in environment block
- ;at return, es:di -> start of env str
- ;cx is length of env str
- jc env_set_add ;if not found, just add
-
- call env_var_remove ;remove variable at es:di from env
- cmp dx,0 ;check out length of data to add
- je env_set_exit ;if zero, just exit
-
- env_set_add:
- mov cx,bx ;restore length of variable
- call env_var_add ;add new variable to set string
- jc env_set_no_space
- jmp env_set_exit
-
- env_set_no_space:
- mov dx,offset env_set_nospace
- jmp env_set_type
-
- env_set_syntax_err:
- mov dx,offset env_set_syntax
- env_set_type:
- push cs
- pop ds
- call type_string
- env_set_error:
- stc
- env_set_exit:
- pop si
- pop es
- pop ds
- pop di
- pop cx
- pop bx
- pop ax
- ret
- env_set endp
-
- code_seg ends
- end
-
- CURRENT_DIR DB 0 ;
- WORKING_DIR EQU CURRENT_DIR+68 ;
- PURGE_DIR EQU CURRENT_DIR+136
- SOURCE EQU CURRENT_DIR+202
- TARGET EQU CURRENT_DIR+280 ;
- ENTRY EQU CURRENT_DIR+358
- BUFFER EQU CURRENT_DIR+394 ;
-
- ;
- ;
- ;
- CODE ENDS
- END START